Annotation of 43BSD/contrib/mh/sbr/m_convert.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.