2 ** fmt_addr.c -- format an address field (from fmt_scan)
4 ** This code is Copyright (c) 2002, by the authors of nmh. See the
5 ** COPYRIGHT file in the root directory of the nmh distribution for
6 ** complete copyright information.
10 #include <h/addrsbr.h>
11 #include <h/fmt_scan.h>
14 static char *buf; /* our current working buffer */
15 static char *bufend; /* end of working buffer */
16 static char *last_dst; /* buf ptr at end of last call */
17 static unsigned int bufsiz; /* current size of buf */
19 #define BUFINCR 512 /* how much to expand buf when if fills */
21 #define CPY(s) { cp = (s); while ((*dst++ = *cp++)) ; --dst; }
23 /* check if there's enough room in buf for str. add more mem if needed */
24 #define CHECKMEM(str) \
25 if ((len = strlen(str)) >= bufend - dst) {\
27 int n = last_dst - buf;\
28 bufsiz += ((dst + len - bufend) / BUFINCR + 1) * BUFINCR;\
29 buf = mh_xrealloc(buf, bufsiz);\
32 bufend = buf + bufsiz;\
37 ** fmt_scan will call this routine if the user includes the function
38 ** "(formataddr {component})" in a format string. "orig" is the
39 ** original contents of the string register. "str" is the address
40 ** string to be formatted and concatenated onto orig. This routine
41 ** returns a pointer to the concatenated address string.
43 ** We try to not do a lot of malloc/copy/free's (which is why we
44 ** don't call "getcpy") but still place no upper limit on the
45 ** length of the result string.
47 ** This routine is placed in a separate library so it can be
48 ** overridden by particular programs (e.g., "replsbr").
52 formataddr(char *orig, char *str)
59 register struct mailname *mp = NULL;
61 /* if we don't have a buffer yet, get one */
63 buf = mh_xmalloc(BUFINCR);
64 last_dst = buf; /* XXX */
65 bufsiz = BUFINCR - 6; /* leave some slop */
66 bufend = buf + bufsiz;
69 ** If "orig" points to our buffer we can just pick up where we
70 ** left off. Otherwise we have to copy orig into our buffer.
74 else if (!orig || !*orig) {
78 dst = last_dst; /* XXX */
83 /* concatenate all the new addresses onto 'buf' */
84 for (isgroup = 0; (cp = getname(str)); ) {
85 if ((mp = getm(cp, NULL, 0, fmt_norm, NULL)) == NULL)
88 if (isgroup && (mp->m_gname || !mp->m_ingrp)) {
92 /* if we get here we're going to add an address */
98 CHECKMEM(mp->m_gname);