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