|
|
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 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.