Added -clobber switch to mhstore(1) [Bug #11160].
[mmh] / docs / historical / mh-6.8.5 / sbr / RCS / m_convert.c,v
1 head    1.10;
2 access;
3 symbols;
4 locks; strict;
5 comment @ * @;
6
7
8 1.10
9 date    92.12.15.00.20.22;      author jromine; state Exp;
10 branches;
11 next    1.9;
12
13 1.9
14 date    92.10.26.22.53.13;      author jromine; state Exp;
15 branches;
16 next    1.8;
17
18 1.8
19 date    92.01.31.21.49.42;      author jromine; state Exp;
20 branches;
21 next    1.7;
22
23 1.7
24 date    91.02.12.16.51.00;      author mh;      state Exp;
25 branches;
26 next    1.6;
27
28 1.6
29 date    91.01.09.11.19.24;      author mh;      state Exp;
30 branches;
31 next    1.5;
32
33 1.5
34 date    90.12.26.16.41.46;      author mh;      state Exp;
35 branches;
36 next    1.4;
37
38 1.4
39 date    90.04.05.15.31.48;      author sources; state Exp;
40 branches;
41 next    1.3;
42
43 1.3
44 date    90.04.05.14.49.04;      author sources; state Exp;
45 branches;
46 next    1.2;
47
48 1.2
49 date    90.02.06.13.05.17;      author sources; state Exp;
50 branches;
51 next    1.1;
52
53 1.1
54 date    90.02.06.13.03.55;      author sources; state Exp;
55 branches;
56 next    ;
57
58
59 desc
60 @@
61
62
63 1.10
64 log
65 @endif sugar
66 @
67 text
68 @/* m_convert.c - parse a message sequence and set SELECTED */
69 #ifndef lint
70 static char ident[] = "@@(#)$Id: m_convert.c,v 1.9 1992/10/26 22:53:13 jromine Exp jromine $";
71 #endif  /* lint */
72
73 #include "../h/mh.h"
74 #include <stdio.h>
75 #include <ctype.h>
76
77 #define BADMSG  (-2)
78 #define BADRNG  (-3)
79 #define BADNEW  (-4)
80 #define BADNUM  (-5)
81 #define BADLST  (-6)
82
83 #define FIRST   1
84 #define LAST    2
85
86 #define getnew(mp)      (mp -> hghmsg + 1)
87
88 static int  convdir;
89 static char *delimp;
90
91 static m_conv(), attr();
92 /* \f */
93
94 m_convert (mp, name)
95 register struct msgs *mp;
96 register char   *name;
97 {
98     register int    first,
99                     last;
100     register char  *bp,
101                    *cp;
102     int     found,
103             range,
104             err,
105             flags;
106
107     switch (err = attr (mp, cp = name)) {
108         case NOTOK: 
109             return 0;
110
111         case OK: 
112             break;
113
114         default: 
115             if (err < 0)
116                 goto badmsg;
117             return 1;
118     }
119
120     found = 0;
121     flags = mp -> msgflags & MHPATH ? EXISTS | SELECT_EMPTY : EXISTS;
122
123     if ((mp -> msgflags & MHPATH) && strcmp (cp, "new") == 0)
124         if ((err = first = getnew (mp)) <= 0)
125             goto badmsg;
126         else
127             goto single;
128     if (strcmp (cp, "all") == 0)
129         cp = "first-last";
130     if ((err = first = m_conv (mp, cp, FIRST)) <= 0)
131         goto badmsg;
132     if (*(cp = delimp) && *cp != '-' && *cp != ':') {
133 badelim: ;
134         advise (NULLCP, "illegal argument delimiter: `%c'(0%o)",
135                 *delimp, *delimp);
136         return 0;
137     }
138     if (*cp == '-') {
139         cp++;
140         if ((err = last = m_conv (mp, cp, LAST)) <= 0) {
141     badmsg: ;
142             switch (err) {
143                 case BADMSG: 
144                     advise (NULLCP, "no %s message", cp);
145                     break;
146
147                 case BADNUM: 
148                     advise (NULLCP, "message %s doesn't exist", cp);
149                     break;
150
151                 case BADRNG: 
152                     advise (NULLCP, "message %s out of range 1-%d",
153                             cp, mp -> hghmsg);
154                     break;
155
156                 case BADLST: 
157             badlist: ;
158                     advise (NULLCP, "bad message list %s", name);
159                     break;
160
161                 case BADNEW:
162                     advise (NULLCP, "folder full, no %s message", name);
163                     break;
164
165                 default: 
166                     advise (NULLCP, "no messages match specification");
167             }
168             return 0;
169         }
170         if (last < first)
171             goto badlist;
172         if (*delimp)
173             goto badelim;
174         if (first > mp -> hghmsg || last < mp -> lowmsg) {
175     rangerr: ;
176             advise (NULLCP, "no messages in range %s", name);
177             return 0;
178         }
179         if (last > mp -> hghmsg)
180             last = mp -> hghmsg;
181         if (first < mp -> lowmsg)
182             first = mp -> lowmsg;
183         }
184     else
185         if (*cp == ':') {
186             cp++;
187             if (*cp == '-') {
188                 convdir = -1;
189                 cp++;
190             }
191             else
192                 if (*cp == '+') {
193                     convdir = 1;
194                     cp++;
195                 }
196             if ((range = atoi (bp = cp)) == 0)
197                 goto badlist;
198             while (isdigit (*bp))
199                 bp++;
200             if (*bp)
201                 goto badelim;
202             if ((convdir > 0 && first > mp -> hghmsg)
203                     || (convdir < 0 && first < mp -> lowmsg))
204                 goto rangerr;
205             if (first < mp -> lowmsg)
206                 first = mp -> lowmsg;
207             if (first > mp -> hghmsg)
208                 first = mp -> hghmsg;
209             for (last = first;
210                     last >= mp -> lowmsg && last <= mp -> hghmsg;
211                     last += convdir)
212                 if (mp -> msgstats[last] & EXISTS)
213                     if (--range <= 0)
214                         break;
215             if (last < mp -> lowmsg)
216                 last = mp -> lowmsg;
217             if (last > mp -> hghmsg)
218                 last = mp -> hghmsg;
219             if (last < first) {
220                 range = last;
221                 last = first;
222                 first = range;
223             }
224         }
225         else {
226             if (!(mp -> msgflags & MHPATH))
227                 if (first > mp -> hghmsg
228                         || first < mp -> lowmsg
229                         || !(mp -> msgstats[first] & EXISTS)) {
230                     if (strcmp (name, "cur") == 0 || strcmp (name, ".") == 0)
231                         advise (NULLCP, "no %s message", name);
232                     else
233                         advise (NULLCP, "message %d doesn't exist", first);
234                     return 0;
235                 }
236     single: ;
237             last = first;
238             if (mp -> msgflags & MHPATH)
239                 mp -> msgstats[first] |= SELECT_EMPTY;
240         }
241     for (; first <= last; first++)
242         if (mp -> msgstats[first] & flags) {
243             if (!(mp -> msgstats[first] & SELECTED)) {
244                 mp -> numsel++;
245                 mp -> msgstats[first] |= SELECTED;
246                 if (mp -> lowsel == 0 || first < mp -> lowsel)
247                     mp -> lowsel = first;
248                 if (first > mp -> hghsel)
249                     mp -> hghsel = first;
250             }
251             found++;
252         }
253     if (!found)
254         goto rangerr;
255
256     return 1;
257 }
258
259 /* \f */
260
261 static  m_conv (mp, str, call)
262 register struct msgs *mp;
263 register char   *str;
264 register int     call;
265 {
266     register int    i;
267     register char  *cp,
268                    *bp;
269     char    buf[16];
270
271     convdir = 1;
272     cp = bp = str;
273     if (isdigit (*cp)) {
274         while (isdigit (*bp))
275             bp++;
276         delimp = bp;
277         return ((i = atoi (cp)) <= mp -> hghmsg ? i
278                 : *delimp || call == LAST ? mp -> hghmsg + 1
279                 : mp -> msgflags & MHPATH ? BADRNG : BADNUM);
280     }
281
282     bp = buf;
283 #ifndef LOCALE
284     while ((*cp >= 'a' && *cp <= 'z') || *cp == '.')
285 #else
286     while (isalpha(*cp) || *cp == '.')  /* doesn't enforce lower case */
287 #endif /* LOCALE */
288         *bp++ = *cp++;
289     *bp++ = 0;
290     delimp = cp;
291
292     if (strcmp (buf, "first") == 0)
293         return (mp -> hghmsg || !(mp -> msgflags & MHPATH)
294                 ? mp -> lowmsg : BADMSG);
295
296     if (strcmp (buf, "last") == 0) {
297         convdir = -1;
298         return (mp -> hghmsg || !(mp -> msgflags & MHPATH)
299                 ? mp -> hghmsg : BADMSG);
300     }
301
302     if (strcmp (buf, "cur") == 0 || strcmp (buf, ".") == 0)
303         return (mp -> curmsg > 0 ? mp -> curmsg : BADMSG);
304
305     if (strcmp (buf, "prev") == 0) {
306         convdir = -1;
307         for (i = (mp -> curmsg <= mp -> hghmsg) ? mp -> curmsg - 1 : mp -> hghmsg;
308                 i >= mp -> lowmsg; i--) {
309             if (mp -> msgstats[i] & EXISTS)
310                 return i;
311         }
312         return BADMSG;
313     }
314
315     if (strcmp (buf, "next") == 0) {
316         for (i = (mp -> curmsg >= mp -> lowmsg) ? mp -> curmsg + 1 : mp -> lowmsg;
317                 i <= mp -> hghmsg; i++) {
318             if (mp -> msgstats[i] & EXISTS)
319                 return i;
320         }
321         return BADMSG;
322     }
323
324     return BADLST;
325 }
326
327 /* \f */
328
329 static  attr (mp, cp)
330 register struct msgs *mp;
331 register char   *cp;
332 {
333     char   *bp = (char *)NULL;
334     int     bits,
335             found,
336             inverted,
337             range = 0,          /* no range */
338             first = 0;
339     register int    i,
340                     j;
341     register char  *dp;
342
343     if (strcmp (cp, "cur") == 0)/* hack for "cur-xyz", etc. */
344         return OK;
345     if (ssequal ("cur:", cp))   /* this code need to be rewritten... */
346         return OK;
347
348     if (inverted = (dp = m_find (nsequence)) && *dp && ssequal (dp, cp))
349         cp += strlen (dp);
350
351     convdir = 1;
352     for (dp = cp; *dp && isalnum(*dp); dp++)
353         continue;
354     if (*dp == ':') {
355         bp = dp++;
356
357         range = 1;
358         if (isalpha (*dp)) {    /* optimize? */
359             if (strcmp (dp, "prev") == 0) {
360                 convdir = -1;
361                 first = (mp -> curmsg > 0) && (mp -> curmsg <= mp -> hghmsg)
362                         ? mp -> curmsg - 1
363                         : mp -> hghmsg;
364             }
365             else if (strcmp (dp, "next") == 0) {
366                 convdir = 1;
367                 first = (mp -> curmsg >= mp -> lowmsg)
368                             ? mp -> curmsg + 1
369                             : mp -> lowmsg;
370             }
371             else if (strcmp (dp, "first") == 0) {
372                 convdir = 1;
373             }
374             else if (strcmp (dp, "last") == 0) {
375                 convdir = -1;
376             }
377             else
378                 return BADLST;
379         }
380         else {                  /* a numeric range */
381             if (*dp == '+')
382                 dp++;
383             else if (*dp == '-') {
384                 dp++;
385                 convdir = -1;
386             }
387             if ((range = atoi(dp)) == 0)
388                 return BADLST;
389             while (isdigit (*dp))
390                 dp++;
391             if (*dp)
392                 return BADLST;
393         }
394
395         *bp = '\0';             /* terminate sequence name */
396     }
397
398
399     bits = FFATTRSLOT;
400     for (i = 0; mp -> msgattrs[i]; i++)
401         if (strcmp (mp -> msgattrs[i], cp) == 0)
402             break;
403     if (bp)
404         *bp = ':';              /* restore sequence name */
405     if (mp -> msgattrs[i] == NULL)
406         return OK;
407
408     found = 0;
409     for (j = first ? first : (convdir > 0) ? mp -> lowmsg : mp -> hghmsg;
410                 j >= mp -> lowmsg && j <= mp -> hghmsg; j += convdir)
411         if ((mp -> msgstats[j] & EXISTS)
412                 && inverted ? !(mp -> msgstats[j] & (1 << (bits + i)))
413                 : mp -> msgstats[j] & (1 << (bits + i))) {
414             if (!(mp -> msgstats[j] & SELECTED)) {
415                 mp -> numsel++;
416                 mp -> msgstats[j] |= SELECTED;
417                 if (mp -> lowsel == 0 || j < mp -> lowsel)
418                     mp -> lowsel = j;
419                 if (j > mp -> hghsel)
420                     mp -> hghsel = j;
421             }
422             found++;
423             if (range && found >= range)
424                 break;          /* we've done enough */
425         }
426     if (found > 0)
427         return found;
428
429     if (first)
430         return BADMSG;
431     advise (NULLCP, "sequence %s %s", cp, inverted ? "full" : "empty");
432     return NOTOK;
433 }
434 @
435
436
437 1.9
438 log
439 @LOCALE
440 @
441 text
442 @d3 2
443 a4 2
444 static char ident[] = "@@(#)$Id: m_convert.c,v 1.8 1992/01/31 21:49:42 jromine Exp jromine $";
445 #endif  lint
446 @
447
448
449 1.8
450 log
451 @kerberos
452 @
453 text
454 @d3 1
455 a3 1
456 static char ident[] = "@@(#)$Id: m_convert.c,v 1.7 1991/02/12 16:51:00 mh Exp jromine $";
457 d216 1
458 d218 3
459 @
460
461
462 1.7
463 log
464 @fix bug. - this code need to be reorganized.
465 /jlr
466 @
467 text
468 @d3 1
469 a3 1
470 static char ident[] = "@@(#)$Id: m_convert.c,v 1.6 91/01/09 11:19:24 mh Exp Locker: mh $";
471 d218 1
472 a218 1
473     *bp++ = NULL;
474 @
475
476
477 1.6
478 log
479 @allow sequence:{first,last,next,prev}
480 jlr
481 @
482 text
483 @d3 1
484 a3 1
485 static char ident[] = "@@(#)$Id: m_convert.c,v 1.5 90/12/26 16:41:46 mh Exp Locker: mh $";
486 d273 2
487 @
488
489
490 1.5
491 log
492 @add sequence ranges (e.g., sel:10)
493 jlr
494 @
495 text
496 @d3 1
497 a3 1
498 static char ident[] = "@@(#)$Id: m_convert.c,v 1.4 90/04/05 15:31:48 sources Exp Locker: mh $";
499 d262 1
500 a262 1
501     char   *bp;
502 d266 2
503 a267 1
504             range = 0;          /* no range */
505 d281 25
506 a305 7
507     if (*(bp = dp) == ':') {
508         dp++;
509         if (*dp == '+')
510             dp++;
511         else if (*dp == '-') {
512             dp++;
513             convdir = -1;
514 d307 16
515 a322 7
516         if ((range = atoi(dp)) == 0)
517             return BADLST;
518         while (isdigit (*dp))
519             dp++;
520         if (*dp)
521             return BADLST;
522         *bp = '\0';
523 d325 1
524 d330 2
525 d336 2
526 a337 2
527     for (j = convdir > 0 ? mp -> lowmsg : mp -> hghmsg;
528             j >= mp -> lowmsg && j <= mp -> hghmsg; j += convdir)
529 d356 2
530 @
531
532
533 1.4
534 log
535 @add ID
536 @
537 text
538 @d3 1
539 a3 1
540 static char ident[] = "@@(#)$Id:$";
541 a9 1
542 #define BADLST  (-1)
543 d14 1
544 d48 2
545 d262 1
546 d265 2
547 a266 1
548             inverted;
549 d277 20
550 d305 2
551 a306 1
552     for (j = mp -> lowmsg; j <= mp -> hghmsg; j++)
553 d319 2
554 @
555
556
557 1.3
558 log
559 @add ID
560 @
561 text
562 @d3 1
563 a3 1
564 static char ident[] = "$Id:";
565 @
566
567
568 1.2
569 log
570 @ANSI Compilance
571 @
572 text
573 @d2 3
574 @
575
576
577 1.1
578 log
579 @Initial revision
580 @
581 text
582 @d21 1
583 @