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