From: Ken Hornstein Date: Wed, 20 Feb 2013 17:01:05 +0000 (-0500) Subject: Support callbacks into the format engine. This is so we can add in proper X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/59620a0948c8b5a2782400580d1487fb4b9b8d39?ds=sidebyside;hp=--cc Support callbacks into the format engine. This is so we can add in proper hooks for %(formataddr), %(concataddr), and (eventually) tracing. --- 59620a0948c8b5a2782400580d1487fb4b9b8d39 diff --git a/h/fmt_scan.h b/h/fmt_scan.h index b2ec6704..e499d51d 100644 --- a/h/fmt_scan.h +++ b/h/fmt_scan.h @@ -81,6 +81,20 @@ struct format { * prototypes used by the format engine */ +/* + * These are the definitions used by the callbacks for fmt_scan() + */ + +typedef char * (*formataddr_cb)(char *, char *); +typedef char * (*concataddr_cb)(char *, char *); +typedef void (*trace_cb)(void *, int, int, char *, char *); + +struct fmt_callbacks { + formataddr_cb formataddr; + concataddr_cb concataddr; + trace_cb trace; +}; + /* * Create a new format string. Arguments are: * @@ -140,12 +154,20 @@ int fmt_compile (char *fstring, struct format **fmt, int reset); * dat[3] - %(width) * dat[4] - %(unseen) * + * callbacks - A set of a callback functions used by the format engine. + * Can be NULL. If structure elements are NULL, a default + * function will be used. Callback structure elements are: + * + * formataddr - A callback for the %(formataddr) instruction + * concataddr - A callback for the %(concataddr) instruction + * trace - Called for every format instruction executed + * * The return value is a pointer to the next format instruction to * execute, which is currently always NULL. */ struct format *fmt_scan (struct format *format, char *scanl, size_t max, - int width, int *dat); + int width, int *dat, struct fmt_callbacks *callbacks); /* * Free a format structure and/or component hash table. Arguments are: diff --git a/sbr/fmt_scan.c b/sbr/fmt_scan.c index 879f7716..8e7827fd 100644 --- a/sbr/fmt_scan.c +++ b/sbr/fmt_scan.c @@ -328,7 +328,8 @@ get_x400_comp (char *mbox, char *key, char *buffer, int buffer_len) } struct format * -fmt_scan (struct format *format, char *scanl, size_t max, int width, int *dat) +fmt_scan (struct format *format, char *scanl, size_t max, int width, int *dat, + struct fmt_callbacks *callbacks) { char *cp, *ep; unsigned char *sp; @@ -877,12 +878,18 @@ fmt_scan (struct format *format, char *scanl, size_t max, int width, int *dat) case FT_FORMATADDR: /* hook for custom address list formatting (see replsbr.c) */ - str = formataddr (savestr, str); + if (callbacks && callbacks->formataddr) + str = callbacks->formataddr (savestr, str); + else + str = formataddr (savestr, str); break; case FT_CONCATADDR: /* The same as formataddr, but doesn't do duplicate suppression */ - str = concataddr (savestr, str); + if (callbacks && callbacks->concataddr) + str = callbacks->concataddr (savestr, str); + else + str = concataddr (savestr, str); break; case FT_PUTADDR: diff --git a/uip/ap.c b/uip/ap.c index 105c3fe4..c42d732c 100644 --- a/uip/ap.c +++ b/uip/ap.c @@ -198,7 +198,7 @@ process (char *arg, int length, int norm) p->pq_error = NULL; } - fmt_scan (fmt, buffer, sizeof buffer - 1, length, dat); + fmt_scan (fmt, buffer, sizeof buffer - 1, length, dat, NULL); fputs (buffer, stdout); if (p->pq_text) diff --git a/uip/comp.c b/uip/comp.c index 0b0ac369..416a8854 100644 --- a/uip/comp.c +++ b/uip/comp.c @@ -379,7 +379,7 @@ try_it_again: dat[2] = 0; dat[3] = outputlinelen; dat[4] = 0; - fmt_scan(fmt, scanl, i + 1, i, dat); + fmt_scan(fmt, scanl, i + 1, i, dat, NULL); write(out, scanl, strlen(scanl)); free(scanl); } else { diff --git a/uip/dp.c b/uip/dp.c index eef77908..67eef061 100644 --- a/uip/dp.c +++ b/uip/dp.c @@ -149,7 +149,7 @@ process (char *date, int length) free(cptr->c_text); cptr->c_text = getcpy(date); } - fmt_scan (fmt, buffer, sizeof buffer - 1, length, dat); + fmt_scan (fmt, buffer, sizeof buffer - 1, length, dat, NULL); fputs (buffer, stdout); return status; diff --git a/uip/fmttest.c b/uip/fmttest.c index 7e715721..687cb50e 100644 --- a/uip/fmttest.c +++ b/uip/fmttest.c @@ -369,7 +369,7 @@ process_addresses(struct format *fmt, struct msgs_array *addrs, char *buffer, p->pq_error = NULL; } - fmt_scan(fmt, buffer, bufsize, outwidth, dat); + fmt_scan(fmt, buffer, bufsize, outwidth, dat, NULL); fputs(buffer, stdout); if (p->pq_text) @@ -520,7 +520,7 @@ process_messages(struct format *fmt, struct msgs_array *comps, } finished: fclose(in); - fmt_scan(fmt, buffer, bufsize, outwidth, dat); + fmt_scan(fmt, buffer, bufsize, outwidth, dat, NULL); fputs(buffer, stdout); } } @@ -558,7 +558,7 @@ process_raw(struct format *fmt, struct msgs_array *text, char *buffer, c->c_text = getcpy(text->msgs[i]); } - fmt_scan(fmt, buffer, bufsize, outwidth, dat); + fmt_scan(fmt, buffer, bufsize, outwidth, dat, NULL); fputs(buffer, stdout); } } diff --git a/uip/forwsbr.c b/uip/forwsbr.c index 86255857..1f181fdd 100644 --- a/uip/forwsbr.c +++ b/uip/forwsbr.c @@ -178,7 +178,7 @@ finished: adios ("dup", "unable to"); line = mh_xmalloc ((unsigned) fmtsize); - fmt_scan (fmt, line, fmtsize - 1, fmtsize, dat); + fmt_scan (fmt, line, fmtsize - 1, fmtsize, dat, NULL); fputs (line, tmp); free (line); if (fclose (tmp)) diff --git a/uip/mhlsbr.c b/uip/mhlsbr.c index e0759334..fc0a1a10 100644 --- a/uip/mhlsbr.c +++ b/uip/mhlsbr.c @@ -1156,7 +1156,8 @@ mcomp_format (struct mcomp *c1, struct mcomp *c2) if (!cp[1]) *cp = 0; - fmt_scan (c1->c_fmt, buffer, sizeof buffer - 1, sizeof buffer - 1, dat); + fmt_scan (c1->c_fmt, buffer, sizeof buffer - 1, sizeof buffer - 1, + dat, NULL); /* Don't need to append a newline, dctime() already did */ c2->c_text = getcpy (buffer); @@ -1189,7 +1190,8 @@ mcomp_format (struct mcomp *c1, struct mcomp *c2) p->pq_error = NULL; } - fmt_scan (c1->c_fmt, buffer, sizeof buffer - 1, sizeof buffer - 1, dat); + fmt_scan (c1->c_fmt, buffer, sizeof buffer - 1, sizeof buffer - 1, + dat, NULL); if (*buffer) { if (c2->c_text) c2->c_text = add (",\n", c2->c_text); @@ -1871,7 +1873,7 @@ filterbody (struct mcomp *c1, char *buf, int bufsz, int state, FILE *fp) for (a = arglist_head, i = 1; a != NULL; a = a->a_next, i++) { args[i] = mh_xmalloc(BUFSIZ); - fmt_scan(a->a_fmt, args[i], BUFSIZ - 1, BUFSIZ, dat); + fmt_scan(a->a_fmt, args[i], BUFSIZ - 1, BUFSIZ, dat, NULL); /* * fmt_scan likes to put a trailing newline at the end of the * format string. If we have one, get rid of it. diff --git a/uip/rcvdist.c b/uip/rcvdist.c index 8f88639a..2db1b050 100644 --- a/uip/rcvdist.c +++ b/uip/rcvdist.c @@ -229,7 +229,7 @@ finished: ; scanl = mh_xmalloc ((size_t) i + 2); dat[0] = dat[1] = dat[2] = dat[4] = 0; dat[3] = outputlinelen; - fmt_scan (fmt, scanl, i + 1, i, dat); + fmt_scan (fmt, scanl, i + 1, i, dat, NULL); fputs (scanl, out); if (ferror (out)) diff --git a/uip/replsbr.c b/uip/replsbr.c index 3dbc3031..21170376 100644 --- a/uip/replsbr.c +++ b/uip/replsbr.c @@ -57,6 +57,8 @@ static char *addrcomps[] = { */ static int insert (struct mailname *); static void replfilter (FILE *, FILE *, char *, int); +static char *replformataddr(char *, char *); +static char *replconcataddr(char *, char *); void @@ -72,6 +74,7 @@ replout (FILE *inb, char *msg, char *drft, struct msgs *mp, int outputlinelen, char name[NAMESZ], *scanl; unsigned char *cp; static int dat[5]; /* aux. data for format routine */ + struct fmt_callbacks cb; FILE *out; NMH_UNUSED (msg); @@ -203,7 +206,10 @@ finished: dat[2] = 0; dat[3] = outputlinelen; dat[4] = 0; - fmt_scan (fmt, scanl, i + 1, i, dat); + memset(&cb, 0, sizeof(cb)); + cb.formataddr = replformataddr; + cb.concataddr = replconcataddr; + fmt_scan (fmt, scanl, i + 1, i, dat, &cb); fputs (scanl, out); if (badaddrs) { fputs ("\nrepl: bad addresses:\n", out); @@ -271,8 +277,8 @@ static unsigned int bufsiz=0; /* current size of buf */ * don't call "getcpy") but still place no upper limit on the * length of the result string. */ -char * -formataddr (char *orig, char *str) +static char * +replformataddr (char *orig, char *str) { register int len; char baddr[BUFSIZ], error[BUFSIZ]; @@ -347,19 +353,19 @@ formataddr (char *orig, char *str) * like formataddr, except that it does NOT suppress duplicate addresses * between calls. * - * As an implementation detail: I thought about splitting out formataddr() + * As an implementation detail: I thought about splitting out replformataddr() * into the generic part and duplicate-suppressing part, but the call to * insert() was buried deep within a couple of loops and I didn't see a * way to do it easily. So instead we simply set a special flag to stop - * the duplicate check and call formataddr(). + * the duplicate check and call replformataddr(). */ -char * -concataddr(char *orig, char *str) +static char * +replconcataddr(char *orig, char *str) { char *cp; nodupcheck = 1; - cp = formataddr(orig, str); + cp = replformataddr(orig, str); nodupcheck = 0; return cp; } diff --git a/uip/scansbr.c b/uip/scansbr.c index b69f4a41..ddfdd841 100644 --- a/uip/scansbr.c +++ b/uip/scansbr.c @@ -338,7 +338,7 @@ finished: } } - fmt_scan (fmt, scanl, scanl_size, slwidth, dat); + fmt_scan (fmt, scanl, scanl_size, slwidth, dat, NULL); if (bodycomp) bodycomp->c_text = saved_c_text;