hooks for %(formataddr), %(concataddr), and (eventually) tracing.
* prototypes used by the format engine
*/
* 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:
*
/*
* Create a new format string. Arguments are:
*
* dat[3] - %(width)
* dat[4] - %(unseen)
*
* 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,
* 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, struct fmt_callbacks *callbacks);
/*
* Free a format structure and/or component hash table. Arguments are:
/*
* Free a format structure and/or component hash table. Arguments are:
-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;
{
char *cp, *ep;
unsigned char *sp;
case FT_FORMATADDR:
/* hook for custom address list formatting (see replsbr.c) */
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 */
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);
- 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)
fputs (buffer, stdout);
if (p->pq_text)
dat[2] = 0;
dat[3] = outputlinelen;
dat[4] = 0;
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 {
write(out, scanl, strlen(scanl));
free(scanl);
} else {
free(cptr->c_text);
cptr->c_text = getcpy(date);
}
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;
fputs (buffer, stdout);
return status;
- fmt_scan(fmt, buffer, bufsize, outwidth, dat);
+ fmt_scan(fmt, buffer, bufsize, outwidth, dat, NULL);
fputs(buffer, stdout);
if (p->pq_text)
fputs(buffer, stdout);
if (p->pq_text)
- fmt_scan(fmt, buffer, bufsize, outwidth, dat);
+ fmt_scan(fmt, buffer, bufsize, outwidth, dat, NULL);
fputs(buffer, stdout);
}
}
fputs(buffer, stdout);
}
}
c->c_text = getcpy(text->msgs[i]);
}
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);
}
}
fputs(buffer, stdout);
}
}
adios ("dup", "unable to");
line = mh_xmalloc ((unsigned) fmtsize);
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))
fputs (line, tmp);
free (line);
if (fclose (tmp))
- 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);
/* Don't need to append a newline, dctime() already did */
c2->c_text = getcpy (buffer);
- 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);
if (*buffer) {
if (c2->c_text)
c2->c_text = add (",\n", c2->c_text);
for (a = arglist_head, i = 1; a != NULL; a = a->a_next, i++) {
args[i] = mh_xmalloc(BUFSIZ);
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.
/*
* fmt_scan likes to put a trailing newline at the end of the
* format string. If we have one, get rid of it.
scanl = mh_xmalloc ((size_t) i + 2);
dat[0] = dat[1] = dat[2] = dat[4] = 0;
dat[3] = outputlinelen;
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))
fputs (scanl, out);
if (ferror (out))
*/
static int insert (struct mailname *);
static void replfilter (FILE *, FILE *, char *, int);
*/
static int insert (struct mailname *);
static void replfilter (FILE *, FILE *, char *, int);
+static char *replformataddr(char *, char *);
+static char *replconcataddr(char *, char *);
char name[NAMESZ], *scanl;
unsigned char *cp;
static int dat[5]; /* aux. data for format routine */
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);
FILE *out;
NMH_UNUSED (msg);
dat[2] = 0;
dat[3] = outputlinelen;
dat[4] = 0;
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);
fputs (scanl, out);
if (badaddrs) {
fputs ("\nrepl: bad addresses:\n", out);
* don't call "getcpy") but still place no upper limit on the
* length of the result string.
*/
* 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];
{
register int len;
char baddr[BUFSIZ], error[BUFSIZ];
* like formataddr, except that it does NOT suppress duplicate addresses
* between calls.
*
* 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
* 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;
{
char *cp;
nodupcheck = 1;
- cp = formataddr(orig, str);
+ cp = replformataddr(orig, str);
nodupcheck = 0;
return cp;
}
nodupcheck = 0;
return cp;
}
- 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;
if (bodycomp)
bodycomp->c_text = saved_c_text;