]> diplodocus.org Git - nmh/blob - sbr/fmt_scan.c
updating changelog, should have been done with last commit
[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 #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 }