|
|
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.