corrected termination condition for fill character introduced in last version
[mmh] / sbr / fmt_scan.c
1
2 /*
3  * fmt_scan.c -- format string interpretation
4  *
5  * $Id$
6  *
7  * This code is Copyright (c) 2002, by the authors of nmh.  See the
8  * COPYRIGHT file in the root directory of the nmh distribution for
9  * complete copyright information.
10  */
11
12 #include <h/mh.h>
13 #include <h/addrsbr.h>
14 #include <h/fmt_scan.h>
15 #include <h/tws.h>
16 #include <h/fmt_compile.h>
17
18 #ifdef TIME_WITH_SYS_TIME
19 # include <sys/time.h>
20 # include <time.h>
21 #else
22 # ifdef TM_IN_SYS_TIME
23 #  include <sys/time.h>
24 # else
25 #  include <time.h>
26 # endif
27 #endif
28
29 #define NFMTS MAXARGS
30
31 extern char *formataddr ();     /* hook for custom address formatting */
32
33 #ifdef LBL
34 struct msgs *fmt_current_folder; /* current folder (set by main program) */
35 #endif
36
37 extern int fmt_norm;            /* defined in sbr/fmt_def.c = AD_NAME */
38 struct mailname fmt_mnull;
39
40 /*
41  * static prototypes
42  */
43 static int match (char *, char *);
44 static char *get_x400_friendly (char *, char *, int);
45 static int get_x400_comp (char *, char *, char *, int);
46
47
48 /*
49  * test if string "sub" appears anywhere in
50  * string "str" (case insensitive).
51  */
52
53 static int
54 match (char *str, char *sub)
55 {
56     int c1, c2;
57     char *s1, *s2;
58
59 #ifdef LOCALE
60     while ((c1 = *sub)) {
61         c1 = (isalpha(c1) && isupper(c1)) ? tolower(c1) : c1;
62         while ((c2 = *str++) && c1 != ((isalpha(c2) && isupper(c2)) ? tolower(c2) : c2))
63             ;
64         if (! c2)
65             return 0;
66         s1 = sub + 1; s2 = str;
67         while ((c1 = *s1++) && ((isalpha(c1) && isupper(c1)) ? tolower(c1) : c1) == ((isalpha(c2 =*s2++) && isupper(c2)) ? tolower(c2) : c2))
68             ;
69         if (! c1)
70             return 1;
71     }
72 #else
73     while ((c1 = *sub)) {
74         while ((c2 = *str++) && (c1 | 040) != (c2 | 040))
75             ;
76         if (! c2)
77             return 0;
78         s1 = sub + 1; s2 = str;
79         while ((c1 = *s1++) && (c1 | 040) == (*s2++ | 040))
80             ;
81         if (! c1)
82             return 1;
83     }
84 #endif
85     return 1;
86 }
87
88 /*
89  * macros to format data
90  */
91
92 #ifdef LOCALE
93 #define PUTSF(cp, str, wid, fill) {\
94                 ljust = 0;\
95                 if ((i = (wid)) < 0) {\
96                         i = -i;\
97                         ljust++;\
98                 }\
99                 if ((sp = (str))) {\
100                         if (ljust) {\
101                                 c = strlen(sp);\
102                                 if (c > i)\
103                                         sp += c - i;\
104                                 else {\
105                                         while( --i >= c && cp < ep)\
106                                                 *cp++ = fill;\
107                                         i++;\
108                                 }\
109                         } else {\
110                             while ((c = (unsigned char) *sp) && (iscntrl(c) || isspace(c)))\
111                                 sp++;\
112                         }\
113                         while ((c = (unsigned char) *sp++) && --i >= 0 && cp < ep)\
114                                 if (isgraph(c)) \
115                                     *cp++ = c;\
116                                 else {\
117                                         while ((c = (unsigned char) *sp) && (iscntrl(c) || isspace(c)))\
118                                                 sp++;\
119                                             *cp++ = ' ';\
120                                 }\
121                 }\
122                 if (!ljust)\
123                 while( --i >= 0 && cp < ep)\
124                     *cp++ = fill;\
125         }
126
127 #define PUTS(cp, str) {\
128                 if ((sp = (str))) {\
129                     while ((c = (unsigned char) *sp) && (iscntrl(c) || isspace(c)))\
130                         sp++;\
131                     while((c = (unsigned char) *sp++) && cp < ep)\
132                         if (isgraph(c)) \
133                             *cp++ = c;\
134                         else {\
135                             while ((c = (unsigned char) *sp) && (iscntrl(c) || isspace(c)))\
136                                 sp++;\
137                             *cp++ = ' ';\
138                         }\
139                 }\
140         }
141
142 #else /* LOCALE */
143 #define PUTSF(cp, str, wid, fill) {\
144                 ljust = 0;\
145                 if ((i = (wid)) < 0) {\
146                         i = -i;\
147                         ljust++;\
148                 }\
149                 if (sp = (str)) {\
150                         if (ljust) {\
151                                 c = strlen(sp);\
152                                 if (c > i)\
153                                         sp += c - i;\
154                                 else {\
155                                         while( --i >= c && cp < ep)\
156                                                 *cp++ = fill;\
157                                         i++;\
158                                 }\
159                         } else {\
160                     while ((c = *sp) && c <= 32)\
161                         sp++;\
162                         }\
163                         while ((c = *sp++) && --i >= 0 && cp < ep)\
164                                 if (c > 32) \
165                             *cp++ = c;\
166                         else {\
167                                         while ((c = *sp) && c <= 32)\
168                                 sp++;\
169                             *cp++ = ' ';\
170                         }\
171                 }\
172                 if (!ljust)\
173                 while( --i >= 0 && cp < ep)\
174                     *cp++ = fill;\
175                 }
176
177 #define PUTS(cp, str) {\
178                 if (sp = (str)) {\
179                     while ((c = *sp) && c <= 32)\
180                         sp++;\
181                     while( (c = *sp++) && cp < ep)\
182                         if ( c > 32 ) \
183                             *cp++ = c;\
184                         else {\
185                             while ( (c = *sp) && c <= 32 )\
186                                 sp++;\
187                             *cp++ = ' ';\
188                         }\
189                 }\
190                 }
191
192 #endif /* LOCALE */
193
194
195 static char *lmonth[] = { "January",  "February","March",   "April",
196                           "May",      "June",    "July",    "August",
197                           "September","October", "November","December" };
198
199 static char *
200 get_x400_friendly (char *mbox, char *buffer, int buffer_len)
201 {
202     char given[BUFSIZ], surname[BUFSIZ];
203
204     if (mbox == NULL)
205         return NULL;
206     if (*mbox == '"')
207         mbox++;
208     if (*mbox != '/')
209         return NULL;
210
211     if (get_x400_comp (mbox, "/PN=", buffer, buffer_len)) {
212         for (mbox = buffer; (mbox = strchr(mbox, '.')); )
213             *mbox++ = ' ';
214
215         return buffer;
216     }
217
218     if (!get_x400_comp (mbox, "/S=", surname, sizeof(surname)))
219         return NULL;
220
221     if (get_x400_comp (mbox, "/G=", given, sizeof(given)))
222         snprintf (buffer, buffer_len, "%s %s", given, surname);
223     else
224         snprintf (buffer, buffer_len, "%s", surname);
225
226     return buffer;
227 }
228
229 static int
230 get_x400_comp (char *mbox, char *key, char *buffer, int buffer_len)
231 {
232     int idx;
233     char *cp;
234
235     if ((idx = stringdex (key, mbox)) < 0
236             || !(cp = strchr(mbox += idx + strlen (key), '/')))
237         return 0;
238
239     snprintf (buffer, buffer_len, "%*.*s", cp - mbox, cp - mbox, mbox);
240     return 1;
241 }
242
243 struct format *
244 fmt_scan (struct format *format, char *scanl, int width, int *dat)
245 {
246     char *cp, *ep, *sp;
247     char *savestr, *str = NULL;
248     char buffer[BUFSIZ], buffer2[BUFSIZ];
249     int i, c, ljust, n;
250     int value = 0;
251     time_t t;
252     struct format *fmt;
253     struct comp *comp;
254     struct tws *tws;
255     struct mailname *mn;
256
257     cp = scanl;
258     ep = scanl + width - 1;
259
260     for (fmt = format; fmt->f_type != FT_DONE; fmt++)
261         switch (fmt->f_type) {
262         case FT_PARSEADDR:
263         case FT_PARSEDATE:
264             fmt->f_comp->c_flags &= ~CF_PARSED;
265             break;
266         }
267
268     fmt = format;
269
270     while (cp < ep) {
271         switch (fmt->f_type) {
272
273         case FT_COMP:
274             PUTS (cp, fmt->f_comp->c_text);
275             break;
276         case FT_COMPF:
277             PUTSF (cp, fmt->f_comp->c_text, fmt->f_width, fmt->f_fill);
278             break;
279
280         case FT_LIT:
281             sp = fmt->f_text;
282             while( (c = *sp++) && cp < ep)
283                 *cp++ = c;
284             break;
285         case FT_LITF:
286             sp = fmt->f_text;
287             ljust = 0;
288             i = fmt->f_width;
289             if (i < 0) {
290                 i = -i;
291                 ljust++;                /* XXX should do something with this */
292             }
293             while( (c = *sp++) && --i >= 0 && cp < ep)
294                 *cp++ = c;
295             while( --i >= 0 && cp < ep)
296                 *cp++ = fmt->f_fill;
297             break;
298
299         case FT_STR:
300             PUTS (cp, str);
301             break;
302         case FT_STRF:
303             PUTSF (cp, str, fmt->f_width, fmt->f_fill);
304             break;
305         case FT_STRFW:
306             adios (NULL, "internal error (FT_STRFW)");
307
308         case FT_NUM:
309             n = snprintf(cp, ep - cp, "%d", value);
310             if (n >= 0) cp += n;
311             break;
312         case FT_NUMF:
313             n = snprintf(cp, ep - cp, "%d", value);
314             if (n >= 0) {
315                 cp += n;
316             } else n = 0;
317             c = abs(fmt->f_width) - n;
318             for (; (c > 0) && (cp < ep); c--) *cp++ = fmt->f_fill;
319             break;
320
321         case FT_CHAR:
322             *cp++ = fmt->f_char;
323             break;
324
325         case FT_DONE:
326             goto finished;
327
328         case FT_IF_S:
329             if (!(value = (str && *str))) {
330                 fmt += fmt->f_skip;
331                 continue;
332             }
333             break;
334
335         case FT_IF_S_NULL:
336             if (!(value = (str == NULL || *str == 0))) {
337                 fmt += fmt->f_skip;
338                 continue;
339             }
340             break;
341
342         case FT_IF_V_EQ:
343             if (value != fmt->f_value) {
344                 fmt += fmt->f_skip;
345                 continue;
346             }
347             break;
348
349         case FT_IF_V_NE:
350             if (value == fmt->f_value) {
351                 fmt += fmt->f_skip;
352                 continue;
353             }
354             break;
355
356         case FT_IF_V_GT:
357             if (value <= fmt->f_value) {
358                 fmt += fmt->f_skip;
359                 continue;
360             }
361             break;
362
363         case FT_IF_MATCH:
364             if (!(value = (str && match (str, fmt->f_text)))) {
365                 fmt += fmt->f_skip;
366                 continue;
367             }
368             break;
369
370         case FT_V_MATCH:
371             if (str)
372                 value = match (str, fmt->f_text);
373             else
374                 value = 0;
375             break;
376
377         case FT_IF_AMATCH:
378             if (!(value = (str && uprf (str, fmt->f_text)))) {
379                 fmt += fmt->f_skip;
380                 continue;
381             }
382             break;
383
384         case FT_V_AMATCH:
385             value = uprf (str, fmt->f_text);
386             break;
387
388         case FT_S_NONNULL:
389             value = (str != NULL && *str != 0);
390             break;
391
392         case FT_S_NULL:
393             value = (str == NULL || *str == 0);
394             break;
395
396         case FT_V_EQ:
397             value = (fmt->f_value == value);
398             break;
399
400         case FT_V_NE:
401             value = (fmt->f_value != value);
402             break;
403
404         case FT_V_GT:
405             value = (fmt->f_value > value);
406             break;
407
408         case FT_GOTO:
409             fmt += fmt->f_skip;
410             continue;
411
412         case FT_NOP:
413             break;
414
415         case FT_LS_COMP:
416             str = fmt->f_comp->c_text;
417             break;
418         case FT_LS_LIT:
419             str = fmt->f_text;
420             break;
421         case FT_LS_GETENV:
422             if (!(str = getenv (fmt->f_text)))
423                 str = "";
424             break;
425         case FT_LS_CFIND:
426             if (!(str = context_find (fmt->f_text)))
427                 str = "";
428             break;
429
430         case FT_LS_DECODECOMP:
431             if (decode_rfc2047(fmt->f_comp->c_text, buffer2))
432                 str = buffer2;
433             else
434                 str = fmt->f_comp->c_text;
435             break;
436
437         case FT_LS_DECODE:
438             if (str && decode_rfc2047(str, buffer2))
439                 str = buffer2;
440             break;
441
442         case FT_LS_TRIM:
443             if (str) {
444                     char *xp;
445
446                     strncpy(buffer, str, sizeof(buffer));
447                     str = buffer;
448                     while (isspace(*str))
449                             str++;
450                     ljust = 0;
451                     if ((i = fmt->f_width) < 0) {
452                             i = -i;
453                             ljust++;
454                     }
455
456                     if (!ljust && i > 0 && strlen(str) > i)
457                             str[i] = '\0';
458                     xp = str;
459                     xp += strlen(str) - 1;
460                     while (xp > str && isspace(*xp))
461                             *xp-- = '\0';
462                     if (ljust && i > 0 && strlen(str) > i)
463                         str += strlen(str) - i;
464             }
465             break;
466
467         case FT_LV_COMPFLAG:
468             value = (fmt->f_comp->c_flags & CF_TRUE) != 0;
469             break;
470         case FT_LV_COMP:
471             value = (comp = fmt->f_comp)->c_text ? atoi(comp->c_text) : 0;
472             break;
473         case FT_LV_LIT:
474             value = fmt->f_value;
475             break;
476         case FT_LV_DAT:
477             value = dat[fmt->f_value];
478             break;
479         case FT_LV_STRLEN:
480             if (str != NULL)
481                     value = strlen(str);
482             else
483                     value = 0;
484             break;
485         case FT_LV_CHAR_LEFT:
486             value = width - (cp - scanl);
487             break;
488         case FT_LV_PLUS_L:
489             value += fmt->f_value;
490             break;
491         case FT_LV_MINUS_L:
492             value = fmt->f_value - value;
493             break;
494         case FT_LV_DIVIDE_L:
495             if (fmt->f_value)
496                 value = value / fmt->f_value;
497             else
498                 value = 0;
499             break;
500         case FT_LV_MODULO_L:
501             if (fmt->f_value)
502                 value = value % fmt->f_value;
503             else
504                 value = 0;
505             break;
506         case FT_SAVESTR:
507             savestr = str;
508             break;
509
510         case FT_LV_SEC:
511             value = fmt->f_comp->c_tws->tw_sec;
512             break;
513         case FT_LV_MIN:
514             value = fmt->f_comp->c_tws->tw_min;
515             break;
516         case FT_LV_HOUR:
517             value = fmt->f_comp->c_tws->tw_hour;
518             break;
519         case FT_LV_MDAY:
520             value = fmt->f_comp->c_tws->tw_mday;
521             break;
522         case FT_LV_MON:
523             value = fmt->f_comp->c_tws->tw_mon + 1;
524             break;
525         case FT_LS_MONTH:
526             str = tw_moty[fmt->f_comp->c_tws->tw_mon];
527             break;
528         case FT_LS_LMONTH:
529             str = lmonth[fmt->f_comp->c_tws->tw_mon];
530             break;
531         case FT_LS_ZONE:
532             str = dtwszone (fmt->f_comp->c_tws);
533             break;
534         case FT_LV_YEAR:
535             value = fmt->f_comp->c_tws->tw_year;
536             break;
537         case FT_LV_WDAY:
538             if (!(((tws = fmt->f_comp->c_tws)->tw_flags) & (TW_SEXP|TW_SIMP)))
539                 set_dotw (tws);
540             value = tws->tw_wday;
541             break;
542         case FT_LS_DAY:
543             if (!(((tws = fmt->f_comp->c_tws)->tw_flags) & (TW_SEXP|TW_SIMP)))
544                 set_dotw (tws);
545             str = tw_dotw[tws->tw_wday];
546             break;
547         case FT_LS_WEEKDAY:
548             if (!(((tws = fmt->f_comp->c_tws)->tw_flags) & (TW_SEXP|TW_SIMP)))
549                 set_dotw (tws);
550             str = tw_ldotw[tws->tw_wday];
551             break;
552         case FT_LV_YDAY:
553             value = fmt->f_comp->c_tws->tw_yday;
554             break;
555         case FT_LV_ZONE:
556             value = fmt->f_comp->c_tws->tw_zone;
557             break;
558         case FT_LV_CLOCK:
559             if ((value = fmt->f_comp->c_tws->tw_clock) == 0)
560                 value = dmktime(fmt->f_comp->c_tws);
561             break;
562         case FT_LV_RCLOCK:
563             if ((value = fmt->f_comp->c_tws->tw_clock) == 0)
564                 value = dmktime(fmt->f_comp->c_tws);
565             value = time((time_t *) 0) - value;
566             break;
567         case FT_LV_DAYF:
568             if (!(((tws = fmt->f_comp->c_tws)->tw_flags) & (TW_SEXP|TW_SIMP)))
569                 set_dotw (tws);
570             switch (fmt->f_comp->c_tws->tw_flags & TW_SDAY) {
571                 case TW_SEXP:
572                     value = 1; break;
573                 case TW_SIMP:
574                     value = 0; break;
575                 default:
576                     value = -1; break;
577             }
578         case FT_LV_ZONEF:
579             if ((fmt->f_comp->c_tws->tw_flags & TW_SZONE) == TW_SZEXP)
580                     value = 1;
581             else
582                     value = -1;
583             break;
584         case FT_LV_DST:
585             value = fmt->f_comp->c_tws->tw_flags & TW_DST;
586             break;
587         case FT_LS_822DATE:
588             str = dasctime (fmt->f_comp->c_tws , TW_ZONE);
589             break;
590         case FT_LS_PRETTY:
591             str = dasctime (fmt->f_comp->c_tws, TW_NULL);
592             break;
593
594         case FT_LS_PERS:
595             str = fmt->f_comp->c_mn->m_pers;
596             break;
597         case FT_LS_MBOX:
598             str = fmt->f_comp->c_mn->m_mbox;
599             break;
600         case FT_LS_HOST:
601             str = fmt->f_comp->c_mn->m_host;
602             break;
603         case FT_LS_PATH:
604             str = fmt->f_comp->c_mn->m_path;
605             break;
606         case FT_LS_GNAME:
607             str = fmt->f_comp->c_mn->m_gname;
608             break;
609         case FT_LS_NOTE:
610             str = fmt->f_comp->c_mn->m_note;
611             break;
612         case FT_LS_822ADDR:
613             str = adrformat( fmt->f_comp->c_mn );
614             break;
615         case FT_LV_HOSTTYPE:
616             value = fmt->f_comp->c_mn->m_type;
617             break;
618         case FT_LV_INGRPF:
619             value = fmt->f_comp->c_mn->m_ingrp;
620             break;
621         case FT_LV_NOHOSTF:
622             value = fmt->f_comp->c_mn->m_nohost;
623             break;
624         case FT_LS_ADDR:
625         case FT_LS_FRIENDLY:
626             if ((mn = fmt->f_comp->c_mn) == &fmt_mnull) {
627                 str = fmt->f_comp->c_text;
628                 break;
629             }
630             if (fmt->f_type == FT_LS_ADDR)
631                 goto unfriendly;
632             if ((str = mn->m_pers) == NULL) {
633                 if ((str = mn->m_note)) {
634                     strncpy (buffer, str, sizeof(buffer));
635                     str = buffer;
636                     if (*str == '(')
637                         str++;
638                     sp = str + strlen(str) - 1;
639                     if (*sp == ')') {
640                         *sp-- = '\0';
641                         while (sp >= str)
642                             if (*sp == ' ')
643                                 *sp-- = '\0';
644                             else
645                                 break;
646                     }
647                 } else if (!(str = get_x400_friendly (mn->m_mbox,
648                                 buffer, sizeof(buffer)))) {
649         unfriendly: ;
650                   switch (mn->m_type) {
651                     case LOCALHOST:
652                         str = mn->m_mbox;
653                         break;
654                     case UUCPHOST:
655                         snprintf (buffer, sizeof(buffer), "%s!%s",
656                                 mn->m_host, mn->m_mbox);
657                         str = buffer;
658                         break;
659                     default:
660                         if (mn->m_mbox) {
661                             snprintf (buffer, sizeof(buffer), "%s@%s",
662                                 mn->m_mbox, mn->m_host);
663                             str= buffer;
664                         }
665                         else
666                             str = mn->m_text;
667                         break;
668                   }
669                 }
670             }
671             break;
672
673         case FT_LOCALDATE:
674             comp = fmt->f_comp;
675             if ((t = comp->c_tws->tw_clock) == 0)
676                 t = dmktime(comp->c_tws);
677             tws = dlocaltime(&t);
678             *comp->c_tws = *tws;
679             break;
680
681         case FT_GMTDATE:
682             comp = fmt->f_comp;
683             if ((t = comp->c_tws->tw_clock) == 0)
684                 t = dmktime(comp->c_tws);
685             tws = dgmtime(&t);
686             *comp->c_tws = *tws;
687             break;
688
689         case FT_PARSEDATE:
690             comp = fmt->f_comp;
691             if (comp->c_flags & CF_PARSED)
692                 break;
693             if ((sp = comp->c_text) && (tws = dparsetime(sp))) {
694                 *comp->c_tws = *tws;
695                 comp->c_flags &= ~CF_TRUE;
696             } else if ((comp->c_flags & CF_DATEFAB) == 0) {
697                 memset ((char *) comp->c_tws, 0, sizeof *comp->c_tws);
698                 comp->c_flags = CF_TRUE;
699             }
700             comp->c_flags |= CF_PARSED;
701             break;
702
703         case FT_FORMATADDR:
704             /* hook for custom address list formatting (see replsbr.c) */
705             str = formataddr (savestr, str);
706             break;
707
708         case FT_PUTADDR:
709             /* output the str register as an address component,
710              * splitting it into multiple lines if necessary.  The
711              * value reg. contains the max line length.  The lit.
712              * field may contain a string to prepend to the result
713              * (e.g., "To: ")
714              */
715             {
716             char *lp, *lastb;
717             int indent, wid, len;
718
719             lp = str;
720             wid = value;
721             len = strlen (str);
722             sp = fmt->f_text;
723             indent = strlen (sp);
724             wid -= indent;
725             while( (c = *sp++) && cp < ep)
726                 *cp++ = c;
727             while (len > wid) {
728                 /* try to break at a comma; failing that, break at a
729                  * space.
730                  */
731                 lastb = 0; sp = lp + wid;
732                 while (sp > lp && (c = *--sp) != ',') {
733                     if (! lastb && isspace(c))
734                         lastb = sp - 1;
735                 }
736                 if (sp == lp) {
737                     if (! (sp = lastb)) {
738                         sp = lp + wid - 1;
739                         while (*sp && *sp != ',' && !isspace(*sp))
740                             sp++;
741                         if (*sp != ',')
742                             sp--;
743                     }
744                 }
745                 len -= sp - lp + 1;
746                 while (cp < ep && lp <= sp)
747                     *cp++ = *lp++;
748                 while (isspace(*lp))
749                     lp++, len--;
750                 if (*lp) {
751                     if (cp < ep)
752                         *cp++ = '\n';
753                     for (i=indent; cp < ep && i > 0; i--)
754                         *cp++ = ' ';
755                 }
756             }
757             PUTS (cp, lp);
758             }
759             break;
760
761         case FT_PARSEADDR:
762             comp = fmt->f_comp;
763             if (comp->c_flags & CF_PARSED)
764                 break;
765             if (comp->c_mn != &fmt_mnull)
766                 mnfree (comp->c_mn);
767             if ((sp = comp->c_text) && (sp = getname(sp)) &&
768                 (mn = getm (sp, NULL, 0, fmt_norm, NULL))) {
769                 comp->c_mn = mn;
770                 while (getname(""))
771                     ;
772                 comp->c_flags |= CF_PARSED;
773             } else {
774                 while (getname(""))             /* XXX */
775                     ;
776                 comp->c_mn = &fmt_mnull;
777             }
778             break;
779             
780         case FT_MYMBOX:
781             /*
782              * if there's no component, we say true.  Otherwise we
783              * say "true" only if we can parse the address and it
784              * matches one of our addresses.
785              */
786             comp = fmt->f_comp;
787             if (comp->c_mn != &fmt_mnull)
788                 mnfree (comp->c_mn);
789             if ((sp = comp->c_text) && (sp = getname(sp)) &&
790                 (mn = getm (sp, NULL, 0, AD_NAME, NULL))) {
791                 comp->c_mn = mn;
792                 if (ismymbox(mn))
793                     comp->c_flags |= CF_TRUE;
794                 else
795                     comp->c_flags &= ~CF_TRUE;
796                 while ((sp = getname(sp)))
797                     if ((comp->c_flags & CF_TRUE) == 0 &&
798                         (mn = getm (sp, NULL, 0, AD_NAME, NULL)))
799                         if (ismymbox(mn))
800                             comp->c_flags |= CF_TRUE;
801             } else {
802                 while (getname(""))             /* XXX */
803                     ;
804                 if (comp->c_text == 0)
805                     comp->c_flags |= CF_TRUE;
806                 else
807                     comp->c_flags &= ~CF_TRUE;
808                 comp->c_mn = &fmt_mnull;
809             }
810             break;
811
812         case FT_ADDTOSEQ:
813 #ifdef LBL
814             /* If we're working on a folder (as opposed to a file), add the
815              * current msg to sequence given in literal field.  Don't
816              * disturb string or value registers.
817              */
818             if (fmt_current_folder)
819                     seq_addmsg(fmt_current_folder, fmt->f_text, dat[0], -1);
820 #endif
821             break;
822         }
823         fmt++;
824     }
825 #ifndef JLR
826     finished:;
827     if (cp[-1] != '\n')
828         *cp++ = '\n';
829     *cp   = 0;
830     return ((struct format *)0);
831 #else /* JLR */
832     if (cp[-1] != '\n')
833         *cp++ = '\n';
834     while (fmt->f_type != FT_DONE)
835         fmt++;
836
837     finished:;    
838     *cp = '\0';
839     return (fmt->f_value ? ++fmt : (struct format *) 0);
840
841 #endif /* JLR */
842 }