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