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