Initial revision
[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             break;
678
679         case FT_LOCALDATE:
680             comp = fmt->f_comp;
681             if ((t = comp->c_tws->tw_clock) == 0)
682                 t = dmktime(comp->c_tws);
683             tws = dlocaltime(&t);
684             *comp->c_tws = *tws;
685             break;
686
687         case FT_GMTDATE:
688             comp = fmt->f_comp;
689             if ((t = comp->c_tws->tw_clock) == 0)
690                 t = dmktime(comp->c_tws);
691             tws = dgmtime(&t);
692             *comp->c_tws = *tws;
693             break;
694
695         case FT_PARSEDATE:
696             comp = fmt->f_comp;
697             if ((sp = comp->c_text) && (tws = dparsetime(sp))) {
698                 *comp->c_tws = *tws;
699                 comp->c_flags = 0;
700             } else if (comp->c_flags >= 0) {
701                 memset ((char *) comp->c_tws, 0, sizeof *comp->c_tws);
702                 comp->c_flags = 1;
703             }
704             break;
705
706         case FT_FORMATADDR:
707             /* hook for custom address list formatting (see replsbr.c) */
708             str = formataddr (savestr, str);
709             break;
710
711         case FT_PUTADDR:
712             /* output the str register as an address component,
713              * splitting it into multiple lines if necessary.  The
714              * value reg. contains the max line length.  The lit.
715              * field may contain a string to prepend to the result
716              * (e.g., "To: ")
717              */
718             {
719             char *lp, *lastb;
720             int indent, wid, len;
721
722             lp = str;
723             wid = value;
724             len = strlen (str);
725             sp = fmt->f_text;
726             indent = strlen (sp);
727             wid -= indent;
728             while( (c = *sp++) && cp < ep)
729                 *cp++ = c;
730             while (len > wid) {
731                 /* try to break at a comma; failing that, break at a
732                  * space, failing that, just split the line.
733                  */
734                 lastb = 0; sp = lp + wid;
735                 while (sp > lp && (c = *--sp) != ',') {
736                     if (! lastb && isspace(c))
737                         lastb = sp - 1;
738                 }
739                 if (sp == lp)
740                     if (! (sp = lastb))
741                         sp = lp + wid - 1;
742                 len -= sp - lp + 1;
743                 while (cp < ep && lp <= sp)
744                     *cp++ = *lp++;
745                 *cp++ = '\n';
746                 for (i=indent; cp < ep && i > 0; i--)
747                     *cp++ = ' ';
748                 while (isspace(*lp))
749                     lp++, len--;
750             }
751             PUTS (cp, lp);
752             }
753             break;
754
755         case FT_PARSEADDR:
756             comp = fmt->f_comp;
757             if (comp->c_mn != &fmt_mnull)
758                 mnfree (comp->c_mn);
759             if ((sp = comp->c_text) && (sp = getname(sp)) &&
760                 (mn = getm (sp, NULL, 0, fmt_norm, NULL))) {
761                 comp->c_mn = mn;
762                 while (getname(""))
763                     ;
764             } else {
765                 while (getname(""))             /* XXX */
766                     ;
767                 comp->c_mn = &fmt_mnull;
768             }
769             break;
770             
771         case FT_MYMBOX:
772             /*
773              * if there's no component, we say true.  Otherwise we
774              * say "true" only if we can parse the address and it
775              * matches one of our addresses.
776              */
777             comp = fmt->f_comp;
778             if (comp->c_mn != &fmt_mnull)
779                 mnfree (comp->c_mn);
780             if ((sp = comp->c_text) && (sp = getname(sp)) &&
781                 (mn = getm (sp, NULL, 0, AD_NAME, NULL))) {
782                 comp->c_mn = mn;
783                 comp->c_flags = ismymbox(mn);
784                 while ((sp = getname(sp)))
785                     if (comp->c_flags == 0 &&
786                         (mn = getm (sp, NULL, 0, AD_NAME, NULL)))
787                         comp->c_flags |= ismymbox(mn);
788             } else {
789                 while (getname(""))             /* XXX */
790                     ;
791                 comp->c_flags = (comp->c_text == 0);
792                 comp->c_mn = &fmt_mnull;
793             }
794             break;
795
796         case FT_ADDTOSEQ:
797 #ifdef LBL
798             /* If we're working on a folder (as opposed to a file), add the
799              * current msg to sequence given in literal field.  Don't
800              * disturb string or value registers.
801              */
802             if (fmt_current_folder)
803                     seq_addmsg(fmt_current_folder, fmt->f_text, dat[0], -1);
804 #endif
805             break;
806         }
807         fmt++;
808     }
809 #ifndef JLR
810     finished:;
811     if (cp[-1] != '\n')
812         *cp++ = '\n';
813     *cp   = 0;
814     return ((struct format *)0);
815 #else /* JLR */
816     if (cp[-1] != '\n')
817         *cp++ = '\n';
818     while (fmt->f_type != FT_DONE)
819         fmt++;
820
821     finished:;    
822     *cp = '\0';
823     return (fmt->f_value ? ++fmt : (struct format *) 0);
824
825 #endif /* JLR */
826 }