head 1.10; access; symbols; locks; strict; comment @ * @; 1.10 date 92.12.15.00.20.22; author jromine; state Exp; branches; next 1.9; 1.9 date 92.10.26.22.53.13; author jromine; state Exp; branches; next 1.8; 1.8 date 92.01.31.21.49.42; author jromine; state Exp; branches; next 1.7; 1.7 date 91.02.12.16.51.00; author mh; state Exp; branches; next 1.6; 1.6 date 91.01.09.11.19.24; author mh; state Exp; branches; next 1.5; 1.5 date 90.12.26.16.41.46; author mh; state Exp; branches; next 1.4; 1.4 date 90.04.05.15.31.48; author sources; state Exp; branches; next 1.3; 1.3 date 90.04.05.14.49.04; author sources; state Exp; branches; next 1.2; 1.2 date 90.02.06.13.05.17; author sources; state Exp; branches; next 1.1; 1.1 date 90.02.06.13.03.55; author sources; state Exp; branches; next ; desc @@ 1.10 log @endif sugar @ text @/* m_convert.c - parse a message sequence and set SELECTED */ #ifndef lint static char ident[] = "@@(#)$Id: m_convert.c,v 1.9 1992/10/26 22:53:13 jromine Exp jromine $"; #endif /* lint */ #include "../h/mh.h" #include #include #define BADMSG (-2) #define BADRNG (-3) #define BADNEW (-4) #define BADNUM (-5) #define BADLST (-6) #define FIRST 1 #define LAST 2 #define getnew(mp) (mp -> hghmsg + 1) static int convdir; static char *delimp; static m_conv(), attr(); /* */ m_convert (mp, name) register struct msgs *mp; register char *name; { register int first, last; register char *bp, *cp; int found, range, err, flags; switch (err = attr (mp, cp = name)) { case NOTOK: return 0; case OK: break; default: if (err < 0) goto badmsg; return 1; } found = 0; flags = mp -> msgflags & MHPATH ? EXISTS | SELECT_EMPTY : EXISTS; if ((mp -> msgflags & MHPATH) && strcmp (cp, "new") == 0) if ((err = first = getnew (mp)) <= 0) goto badmsg; else goto single; if (strcmp (cp, "all") == 0) cp = "first-last"; if ((err = first = m_conv (mp, cp, FIRST)) <= 0) goto badmsg; if (*(cp = delimp) && *cp != '-' && *cp != ':') { badelim: ; advise (NULLCP, "illegal argument delimiter: `%c'(0%o)", *delimp, *delimp); return 0; } if (*cp == '-') { cp++; if ((err = last = m_conv (mp, cp, LAST)) <= 0) { badmsg: ; switch (err) { case BADMSG: advise (NULLCP, "no %s message", cp); break; case BADNUM: advise (NULLCP, "message %s doesn't exist", cp); break; case BADRNG: advise (NULLCP, "message %s out of range 1-%d", cp, mp -> hghmsg); break; case BADLST: badlist: ; advise (NULLCP, "bad message list %s", name); break; case BADNEW: advise (NULLCP, "folder full, no %s message", name); break; default: advise (NULLCP, "no messages match specification"); } return 0; } if (last < first) goto badlist; if (*delimp) goto badelim; if (first > mp -> hghmsg || last < mp -> lowmsg) { rangerr: ; advise (NULLCP, "no messages in range %s", name); return 0; } if (last > mp -> hghmsg) last = mp -> hghmsg; if (first < mp -> lowmsg) first = mp -> lowmsg; } else if (*cp == ':') { cp++; if (*cp == '-') { convdir = -1; cp++; } else if (*cp == '+') { convdir = 1; cp++; } if ((range = atoi (bp = cp)) == 0) goto badlist; while (isdigit (*bp)) bp++; if (*bp) goto badelim; if ((convdir > 0 && first > mp -> hghmsg) || (convdir < 0 && first < mp -> lowmsg)) goto rangerr; if (first < mp -> lowmsg) first = mp -> lowmsg; if (first > mp -> hghmsg) first = mp -> hghmsg; for (last = first; last >= mp -> lowmsg && last <= mp -> hghmsg; last += convdir) if (mp -> msgstats[last] & EXISTS) if (--range <= 0) break; if (last < mp -> lowmsg) last = mp -> lowmsg; if (last > mp -> hghmsg) last = mp -> hghmsg; if (last < first) { range = last; last = first; first = range; } } else { if (!(mp -> msgflags & MHPATH)) if (first > mp -> hghmsg || first < mp -> lowmsg || !(mp -> msgstats[first] & EXISTS)) { if (strcmp (name, "cur") == 0 || strcmp (name, ".") == 0) advise (NULLCP, "no %s message", name); else advise (NULLCP, "message %d doesn't exist", first); return 0; } single: ; last = first; if (mp -> msgflags & MHPATH) mp -> msgstats[first] |= SELECT_EMPTY; } for (; first <= last; first++) if (mp -> msgstats[first] & flags) { if (!(mp -> msgstats[first] & SELECTED)) { mp -> numsel++; mp -> msgstats[first] |= SELECTED; if (mp -> lowsel == 0 || first < mp -> lowsel) mp -> lowsel = first; if (first > mp -> hghsel) mp -> hghsel = first; } found++; } if (!found) goto rangerr; return 1; } /* */ static m_conv (mp, str, call) register struct msgs *mp; register char *str; register int call; { register int i; register char *cp, *bp; char buf[16]; convdir = 1; cp = bp = str; if (isdigit (*cp)) { while (isdigit (*bp)) bp++; delimp = bp; return ((i = atoi (cp)) <= mp -> hghmsg ? i : *delimp || call == LAST ? mp -> hghmsg + 1 : mp -> msgflags & MHPATH ? BADRNG : BADNUM); } bp = buf; #ifndef LOCALE while ((*cp >= 'a' && *cp <= 'z') || *cp == '.') #else while (isalpha(*cp) || *cp == '.') /* doesn't enforce lower case */ #endif /* LOCALE */ *bp++ = *cp++; *bp++ = 0; delimp = cp; if (strcmp (buf, "first") == 0) return (mp -> hghmsg || !(mp -> msgflags & MHPATH) ? mp -> lowmsg : BADMSG); if (strcmp (buf, "last") == 0) { convdir = -1; return (mp -> hghmsg || !(mp -> msgflags & MHPATH) ? mp -> hghmsg : BADMSG); } if (strcmp (buf, "cur") == 0 || strcmp (buf, ".") == 0) return (mp -> curmsg > 0 ? mp -> curmsg : BADMSG); if (strcmp (buf, "prev") == 0) { convdir = -1; for (i = (mp -> curmsg <= mp -> hghmsg) ? mp -> curmsg - 1 : mp -> hghmsg; i >= mp -> lowmsg; i--) { if (mp -> msgstats[i] & EXISTS) return i; } return BADMSG; } if (strcmp (buf, "next") == 0) { for (i = (mp -> curmsg >= mp -> lowmsg) ? mp -> curmsg + 1 : mp -> lowmsg; i <= mp -> hghmsg; i++) { if (mp -> msgstats[i] & EXISTS) return i; } return BADMSG; } return BADLST; } /* */ static attr (mp, cp) register struct msgs *mp; register char *cp; { char *bp = (char *)NULL; int bits, found, inverted, range = 0, /* no range */ first = 0; register int i, j; register char *dp; if (strcmp (cp, "cur") == 0)/* hack for "cur-xyz", etc. */ return OK; if (ssequal ("cur:", cp)) /* this code need to be rewritten... */ return OK; if (inverted = (dp = m_find (nsequence)) && *dp && ssequal (dp, cp)) cp += strlen (dp); convdir = 1; for (dp = cp; *dp && isalnum(*dp); dp++) continue; if (*dp == ':') { bp = dp++; range = 1; if (isalpha (*dp)) { /* optimize? */ if (strcmp (dp, "prev") == 0) { convdir = -1; first = (mp -> curmsg > 0) && (mp -> curmsg <= mp -> hghmsg) ? mp -> curmsg - 1 : mp -> hghmsg; } else if (strcmp (dp, "next") == 0) { convdir = 1; first = (mp -> curmsg >= mp -> lowmsg) ? mp -> curmsg + 1 : mp -> lowmsg; } else if (strcmp (dp, "first") == 0) { convdir = 1; } else if (strcmp (dp, "last") == 0) { convdir = -1; } else return BADLST; } else { /* a numeric range */ if (*dp == '+') dp++; else if (*dp == '-') { dp++; convdir = -1; } if ((range = atoi(dp)) == 0) return BADLST; while (isdigit (*dp)) dp++; if (*dp) return BADLST; } *bp = '\0'; /* terminate sequence name */ } bits = FFATTRSLOT; for (i = 0; mp -> msgattrs[i]; i++) if (strcmp (mp -> msgattrs[i], cp) == 0) break; if (bp) *bp = ':'; /* restore sequence name */ if (mp -> msgattrs[i] == NULL) return OK; found = 0; for (j = first ? first : (convdir > 0) ? mp -> lowmsg : mp -> hghmsg; j >= mp -> lowmsg && j <= mp -> hghmsg; j += convdir) if ((mp -> msgstats[j] & EXISTS) && inverted ? !(mp -> msgstats[j] & (1 << (bits + i))) : mp -> msgstats[j] & (1 << (bits + i))) { if (!(mp -> msgstats[j] & SELECTED)) { mp -> numsel++; mp -> msgstats[j] |= SELECTED; if (mp -> lowsel == 0 || j < mp -> lowsel) mp -> lowsel = j; if (j > mp -> hghsel) mp -> hghsel = j; } found++; if (range && found >= range) break; /* we've done enough */ } if (found > 0) return found; if (first) return BADMSG; advise (NULLCP, "sequence %s %s", cp, inverted ? "full" : "empty"); return NOTOK; } @ 1.9 log @LOCALE @ text @d3 2 a4 2 static char ident[] = "@@(#)$Id: m_convert.c,v 1.8 1992/01/31 21:49:42 jromine Exp jromine $"; #endif lint @ 1.8 log @kerberos @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id: m_convert.c,v 1.7 1991/02/12 16:51:00 mh Exp jromine $"; d216 1 d218 3 @ 1.7 log @fix bug. - this code need to be reorganized. /jlr @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id: m_convert.c,v 1.6 91/01/09 11:19:24 mh Exp Locker: mh $"; d218 1 a218 1 *bp++ = NULL; @ 1.6 log @allow sequence:{first,last,next,prev} jlr @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id: m_convert.c,v 1.5 90/12/26 16:41:46 mh Exp Locker: mh $"; d273 2 @ 1.5 log @add sequence ranges (e.g., sel:10) jlr @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id: m_convert.c,v 1.4 90/04/05 15:31:48 sources Exp Locker: mh $"; d262 1 a262 1 char *bp; d266 2 a267 1 range = 0; /* no range */ d281 25 a305 7 if (*(bp = dp) == ':') { dp++; if (*dp == '+') dp++; else if (*dp == '-') { dp++; convdir = -1; d307 16 a322 7 if ((range = atoi(dp)) == 0) return BADLST; while (isdigit (*dp)) dp++; if (*dp) return BADLST; *bp = '\0'; d325 1 d330 2 d336 2 a337 2 for (j = convdir > 0 ? mp -> lowmsg : mp -> hghmsg; j >= mp -> lowmsg && j <= mp -> hghmsg; j += convdir) d356 2 @ 1.4 log @add ID @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id:$"; a9 1 #define BADLST (-1) d14 1 d48 2 d262 1 d265 2 a266 1 inverted; d277 20 d305 2 a306 1 for (j = mp -> lowmsg; j <= mp -> hghmsg; j++) d319 2 @ 1.3 log @add ID @ text @d3 1 a3 1 static char ident[] = "$Id:"; @ 1.2 log @ANSI Compilance @ text @d2 3 @ 1.1 log @Initial revision @ text @d21 1 @