1: /* m_convert.c - parse a message sequence and set SELECTED */
   2: 
   3: #include "../h/mh.h"
   4: #include <stdio.h>
   5: #include <ctype.h>
   6: 
   7: #define BADLST  (-1)
   8: #define BADMSG  (-2)
   9: #define BADRNG  (-3)
  10: #define BADNEW  (-4)
  11: #define BADNUM  (-5)
  12: 
  13: #define FIRST   1
  14: #define LAST    2
  15: 
  16: #define getnew(mp)  (mp -> hghmsg + 1)
  17: 
  18: static int  convdir;
  19: static char *delimp;
  20: 
  21: /*  */
  22: 
  23: m_convert (mp, name)
  24: register struct msgs *mp;
  25: register char   *name;
  26: {
  27:     register int    first,
  28:                     last;
  29:     register char  *bp,
  30:            *cp;
  31:     int     found,
  32:             range,
  33:             err,
  34:             flags;
  35: 
  36:     switch (err = attr (mp, cp = name)) {
  37:     case NOTOK:
  38:         return 0;
  39: 
  40:     case OK:
  41:         break;
  42: 
  43:     default:
  44:         return 1;
  45:     }
  46: 
  47:     found = 0;
  48:     flags = mp -> msgflags & MHPATH ? EXISTS | SELECT_EMPTY : EXISTS;
  49: 
  50:     if ((mp -> msgflags & MHPATH) && strcmp (cp, "new") == 0)
  51:     if ((err = first = getnew (mp)) <= 0)
  52:         goto badmsg;
  53:     else
  54:         goto single;
  55:     if (strcmp (cp, "all") == 0)
  56:     cp = "first-last";
  57:     if ((err = first = m_conv (mp, cp, FIRST)) <= 0)
  58:     goto badmsg;
  59:     if (*(cp = delimp) && *cp != '-' && *cp != ':') {
  60: badelim: ;
  61:     advise (NULLCP, "illegal argument delimiter: `%c'(0%o)",
  62:         *delimp, *delimp);
  63:     return 0;
  64:     }
  65:     if (*cp == '-') {
  66:     cp++;
  67:     if ((err = last = m_conv (mp, cp, LAST)) <= 0) {
  68:     badmsg: ;
  69:         switch (err) {
  70:         case BADMSG:
  71:             advise (NULLCP, "no %s message", cp);
  72:             break;
  73: 
  74:         case BADNUM:
  75:             advise (NULLCP, "message %s doesn't exist", cp);
  76:             break;
  77: 
  78:         case BADRNG:
  79:             advise (NULLCP, "message %s out of range 1-%d",
  80:                 cp, mp -> hghmsg);
  81:             break;
  82: 
  83:         case BADLST:
  84:         badlist: ;
  85:             advise (NULLCP, "bad message list %s", name);
  86:             break;
  87: 
  88:         case BADNEW:
  89:             advise (NULLCP, "folder full, no %s message", name);
  90:             break;
  91: 
  92:         default:
  93:             advise (NULLCP, "no messages match specification");
  94:         }
  95:         return 0;
  96:     }
  97:     if (last < first)
  98:         goto badlist;
  99:     if (*delimp)
 100:         goto badelim;
 101:     if (first > mp -> hghmsg || last < mp -> lowmsg) {
 102:     rangerr: ;
 103:         advise (NULLCP, "no messages in range %s", name);
 104:         return 0;
 105:     }
 106:     if (last > mp -> hghmsg)
 107:         last = mp -> hghmsg;
 108:     if (first < mp -> lowmsg)
 109:         first = mp -> lowmsg;
 110:     }
 111:     else
 112:     if (*cp == ':') {
 113:         cp++;
 114:         if (*cp == '-') {
 115:         convdir = -1;
 116:         cp++;
 117:         }
 118:         else
 119:         if (*cp == '+') {
 120:             convdir = 1;
 121:             cp++;
 122:         }
 123:         if ((range = atoi (bp = cp)) == 0)
 124:         goto badlist;
 125:         while (isdigit (*bp))
 126:         bp++;
 127:         if (*bp)
 128:         goto badelim;
 129:         if ((convdir > 0 && first > mp -> hghmsg)
 130:             || (convdir < 0 && first < mp -> lowmsg))
 131:         goto rangerr;
 132:         if (first < mp -> lowmsg)
 133:         first = mp -> lowmsg;
 134:         if (first > mp -> hghmsg)
 135:         first = mp -> hghmsg;
 136:         for (last = first;
 137:             last >= mp -> lowmsg && last <= mp -> hghmsg;
 138:             last += convdir)
 139:         if (mp -> msgstats[last] & EXISTS)
 140:             if (--range <= 0)
 141:             break;
 142:         if (last < mp -> lowmsg)
 143:         last = mp -> lowmsg;
 144:         if (last > mp -> hghmsg)
 145:         last = mp -> hghmsg;
 146:         if (last < first) {
 147:         range = last;
 148:         last = first;
 149:         first = range;
 150:         }
 151:     }
 152:     else {
 153:         if (!(mp -> msgflags & MHPATH))
 154:         if (first > mp -> hghmsg
 155:             || first < mp -> lowmsg
 156:             || !(mp -> msgstats[first] & EXISTS)) {
 157:             if (strcmp (name, "cur") == 0 || strcmp (name, ".") == 0)
 158:             advise (NULLCP, "no %s message", name);
 159:             else
 160:             advise (NULLCP, "message %d doesn't exist", first);
 161:             return 0;
 162:         }
 163:     single: ;
 164:         last = first;
 165:         if (mp -> msgflags & MHPATH)
 166:         mp -> msgstats[first] |= SELECT_EMPTY;
 167:     }
 168:     for (; first <= last; first++)
 169:     if (mp -> msgstats[first] & flags) {
 170:         if (!(mp -> msgstats[first] & SELECTED)) {
 171:         mp -> numsel++;
 172:         mp -> msgstats[first] |= SELECTED;
 173:         if (mp -> lowsel == 0 || first < mp -> lowsel)
 174:             mp -> lowsel = first;
 175:         if (first > mp -> hghsel)
 176:             mp -> hghsel = first;
 177:         }
 178:         found++;
 179:     }
 180:     if (!found)
 181:     goto rangerr;
 182: 
 183:     return 1;
 184: }
 185: 
 186: /*  */
 187: 
 188: static  m_conv (mp, str, call)
 189: register struct msgs *mp;
 190: register char   *str;
 191: register int     call;
 192: {
 193:     register int    i;
 194:     register char  *cp,
 195:                    *bp;
 196:     char    buf[16];
 197: 
 198:     convdir = 1;
 199:     cp = bp = str;
 200:     if (isdigit (*cp)) {
 201:     while (isdigit (*bp))
 202:         bp++;
 203:     delimp = bp;
 204:     return ((i = atoi (cp)) <= mp -> hghmsg ? i
 205:         : *delimp || call == LAST ? mp -> hghmsg + 1
 206:         : mp -> msgflags & MHPATH ? BADRNG : BADNUM);
 207:     }
 208: 
 209:     bp = buf;
 210:     while ((*cp >= 'a' && *cp <= 'z') || *cp == '.')
 211:     *bp++ = *cp++;
 212:     *bp++ = NULL;
 213:     delimp = cp;
 214: 
 215:     if (strcmp (buf, "first") == 0)
 216:     return (mp -> hghmsg || !(mp -> msgflags & MHPATH)
 217:         ? mp -> lowmsg : BADMSG);
 218: 
 219:     if (strcmp (buf, "last") == 0) {
 220:     convdir = -1;
 221:     return (mp -> hghmsg || !(mp -> msgflags & MHPATH)
 222:         ? mp -> hghmsg : BADMSG);
 223:     }
 224: 
 225:     if (strcmp (buf, "cur") == 0 || strcmp (buf, ".") == 0)
 226:     return (mp -> curmsg > 0 ? mp -> curmsg : BADMSG);
 227: 
 228:     if (strcmp (buf, "prev") == 0) {
 229:     convdir = -1;
 230:     for (i = (mp -> curmsg <= mp -> hghmsg) ? mp -> curmsg - 1 : mp -> hghmsg;
 231:         i >= mp -> lowmsg; i--) {
 232:         if (mp -> msgstats[i] & EXISTS)
 233:         return i;
 234:     }
 235:     return BADMSG;
 236:     }
 237: 
 238:     if (strcmp (buf, "next") == 0) {
 239:     for (i = (mp -> curmsg >= mp -> lowmsg) ? mp -> curmsg + 1 : mp -> lowmsg;
 240:         i <= mp -> hghmsg; i++) {
 241:         if (mp -> msgstats[i] & EXISTS)
 242:         return i;
 243:     }
 244:     return BADMSG;
 245:     }
 246: 
 247:     return BADLST;
 248: }
 249: 
 250: /*  */
 251: 
 252: static  attr (mp, cp)
 253: register struct msgs *mp;
 254: register char   *cp;
 255: {
 256:     int     bits,
 257:             found,
 258:             inverted;
 259:     register int    i,
 260:                     j;
 261:     register char  *dp;
 262: 
 263:     if (strcmp (cp, "cur") == 0)/* hack for "cur-xyz", etc. */
 264:     return OK;
 265: 
 266:     if (inverted = (dp = m_find (nsequence)) && *dp && ssequal (dp, cp))
 267:     cp += strlen (dp);
 268: 
 269:     bits = FFATTRSLOT;
 270:     for (i = 0; mp -> msgattrs[i]; i++)
 271:     if (strcmp (mp -> msgattrs[i], cp) == 0)
 272:         break;
 273:     if (mp -> msgattrs[i] == NULL)
 274:     return OK;
 275: 
 276:     found = 0;
 277:     for (j = mp -> lowmsg; j <= mp -> hghmsg; j++)
 278:     if ((mp -> msgstats[j] & EXISTS)
 279:         && inverted ? !(mp -> msgstats[j] & (1 << (bits + i)))
 280:         : mp -> msgstats[j] & (1 << (bits + i))) {
 281:         if (!(mp -> msgstats[j] & SELECTED)) {
 282:         mp -> numsel++;
 283:         mp -> msgstats[j] |= SELECTED;
 284:         if (mp -> lowsel == 0 || j < mp -> lowsel)
 285:             mp -> lowsel = j;
 286:         if (j > mp -> hghsel)
 287:             mp -> hghsel = j;
 288:         }
 289:         found++;
 290:     }
 291:     if (found > 0)
 292:     return found;
 293: 
 294:     advise (NULLCP, "sequence %s %s", cp, inverted ? "full" : "empty");
 295:     return NOTOK;
 296: }

Defined functions

attr defined in line 252; used 1 times
  • in line 36
m_conv defined in line 188; used 2 times
m_convert defined in line 23; used 1 times

Defined variables

convdir defined in line 18; used 8 times
delimp defined in line 19; used 7 times

Defined macros

BADLST defined in line 7; used 1 times
BADMSG defined in line 8; used 5 times
BADNEW defined in line 10; never used
BADNUM defined in line 11; used 1 times
BADRNG defined in line 9; used 1 times
FIRST defined in line 13; used 1 times
  • in line 57
LAST defined in line 14; used 2 times
getnew defined in line 16; used 1 times
  • in line 51
Last modified: 1986-04-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1743
Valid CSS Valid XHTML 1.0 Strict