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