Rearranged whitespace (and comments) in all the code!
[mmh] / sbr / fmt_addr.c
1 /*
2  * fmt_addr.c -- format an address field (from fmt_scan)
3  *
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.
7  */
8
9 #include <h/mh.h>
10 #include <h/addrsbr.h>
11 #include <h/fmt_scan.h>
12 #include <h/utils.h>
13
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         */
18
19 #define BUFINCR 512  /* how much to expand buf when if fills */
20
21 #define CPY(s) { cp = (s); while ((*dst++ = *cp++)) ; --dst; }
22
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) {\
26                 int i = dst - buf;\
27                 int n = last_dst - buf;\
28                 bufsiz += ((dst + len - bufend) / BUFINCR + 1) * BUFINCR;\
29                 buf = mh_xrealloc (buf, bufsiz);\
30                 dst = buf + i;\
31                 last_dst = buf + n;\
32                 bufend = buf + bufsiz;\
33         }
34
35
36 /* fmt_scan will call this routine if the user includes the function
37  * "(formataddr {component})" in a format string.  "orig" is the
38  * original contents of the string register.  "str" is the address
39  * string to be formatted and concatenated onto orig.  This routine
40  * returns a pointer to the concatenated address string.
41  *
42  * We try to not do a lot of malloc/copy/free's (which is why we
43  * don't call "getcpy") but still place no upper limit on the
44  * length of the result string.
45  *
46  * This routine is placed in a separate library so it can be
47  * overridden by particular programs (e.g., "replsbr").
48  */
49
50 char *
51 formataddr (char *orig, char *str)
52 {
53         register int len;
54         register int isgroup;
55         register char *dst;
56         register char *cp;
57         register char *sp;
58         register struct mailname *mp = NULL;
59
60         /* if we don't have a buffer yet, get one */
61         if (bufsiz == 0) {
62                 buf = mh_xmalloc (BUFINCR);
63                 last_dst = buf;  /* XXX */
64                 bufsiz = BUFINCR - 6;  /* leave some slop */
65                 bufend = buf + bufsiz;
66         }
67         /*
68          * If "orig" points to our buffer we can just pick up where we
69          * left off.  Otherwise we have to copy orig into our buffer.
70          */
71         if (orig == buf)
72                 dst = last_dst;
73         else if (!orig || !*orig) {
74                 dst = buf;
75                 *dst = '\0';
76         } else {
77                 dst = last_dst;  /* XXX */
78                 CHECKMEM (orig);
79                 CPY (orig);
80         }
81
82         /* concatenate all the new addresses onto 'buf' */
83         for (isgroup = 0; (cp = getname (str)); ) {
84                 if ((mp = getm (cp, NULL, 0, fmt_norm, NULL)) == NULL)
85                         continue;
86
87                 if (isgroup && (mp->m_gname || !mp->m_ingrp)) {
88                         *dst++ = ';';
89                         isgroup = 0;
90                 }
91                 /* if we get here we're going to add an address */
92                 if (dst != buf) {
93                         *dst++ = ',';
94                         *dst++ = ' ';
95                 }
96                 if (mp->m_gname) {
97                         CHECKMEM (mp->m_gname);
98                         CPY (mp->m_gname);
99                         isgroup++;
100                 }
101                 sp = adrformat (mp);
102                 CHECKMEM (sp);
103                 CPY (sp);
104                 mnfree (mp);
105         }
106
107         if (isgroup)
108                 *dst++ = ';';
109
110         *dst = '\0';
111         last_dst = dst;
112         return (buf);
113 }