Mercurial > hg > Applications > mh
comparison sbr/formataddr.c @ 0:bce86c4163a3
Initial revision
author | kono |
---|---|
date | Mon, 18 Apr 2005 23:46:02 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:bce86c4163a3 |
---|---|
1 /* formataddr.c - format an address field (from formatsbr) */ | |
2 | |
3 #include "../h/mh.h" | |
4 #include "../h/addrsbr.h" | |
5 #include "../h/formatsbr.h" | |
6 #include <ctype.h> | |
7 #include <stdio.h> | |
8 | |
9 static char *buf; /* our current working buffer */ | |
10 static char *bufend; /* end of working buffer */ | |
11 static char *last_dst; /* buf ptr at end of last call */ | |
12 static unsigned int bufsiz; /* current size of buf */ | |
13 | |
14 #define BUFINCR 512 /* how much to expand buf when if fills */ | |
15 | |
16 #define CPY(s) { cp = (s); while (*dst++ = *cp++) ; --dst; } | |
17 | |
18 /* check if there's enough room in buf for str. add more mem if needed */ | |
19 #define CHECKMEM(str) \ | |
20 if ((len = strlen (str)) >= bufend - dst) {\ | |
21 int i = dst - buf;\ | |
22 int n = last_dst - buf;\ | |
23 bufsiz += ((dst + len - bufend) / BUFINCR + 1) * BUFINCR;\ | |
24 buf = realloc (buf, bufsiz);\ | |
25 dst = buf + i;\ | |
26 last_dst = buf + n;\ | |
27 if (! buf)\ | |
28 adios (NULLCP, "formataddr: couldn't get buffer space");\ | |
29 bufend = buf + bufsiz;\ | |
30 } | |
31 | |
32 | |
33 /* fmtscan will call this routine if the user includes the function | |
34 * "(formataddr {component})" in a format string. "orig" is the | |
35 * original contents of the string register. "str" is the address | |
36 * string to be formatted and concatenated onto orig. This routine | |
37 * returns a pointer to the concatenated address string. | |
38 * | |
39 * We try to not do a lot of malloc/copy/free's (which is why we | |
40 * don't call "getcpy") but still place no upper limit on the | |
41 * length of the result string. | |
42 * | |
43 * This routine is placed in a separate library so it can be | |
44 * overridden by particular programs (e.g., "replsbr"). | |
45 */ | |
46 char *formataddr (orig, str) | |
47 char *orig; | |
48 char *str; | |
49 { | |
50 register int len; | |
51 register int isgroup; | |
52 register char *dst; | |
53 register char *cp; | |
54 register char *sp; | |
55 register struct mailname *mp = NULL; | |
56 | |
57 /* if we don't have a buffer yet, get one */ | |
58 if (bufsiz == 0) { | |
59 buf = malloc (BUFINCR); | |
60 if (! buf) | |
61 adios (NULLCP, "formataddr: couldn't allocate buffer space"); | |
62 last_dst = buf; /* XXX */ | |
63 bufsiz = BUFINCR - 6; /* leave some slop */ | |
64 bufend = buf + bufsiz; | |
65 } | |
66 /* | |
67 * If "orig" points to our buffer we can just pick up where we | |
68 * left off. Otherwise we have to copy orig into our buffer. | |
69 */ | |
70 if (orig == buf) | |
71 dst = last_dst; | |
72 else if (!orig || !*orig) { | |
73 dst = buf; | |
74 *dst = '\0'; | |
75 } else { | |
76 dst = last_dst; /* XXX */ | |
77 CHECKMEM (orig); | |
78 CPY (orig); | |
79 } | |
80 | |
81 /* concatenate all the new addresses onto 'buf' */ | |
82 for (isgroup = 0; cp = getname (str); ) { | |
83 if ((mp = getm (cp, NULLCP, 0, fmt_norm, NULLCP)) == NULL) | |
84 continue; | |
85 | |
86 if (isgroup && (mp->m_gname || !mp->m_ingrp)) { | |
87 *dst++ = ';'; | |
88 isgroup = 0; | |
89 } | |
90 /* if we get here we're going to add an address */ | |
91 if (dst != buf) { | |
92 *dst++ = ','; | |
93 *dst++ = ' '; | |
94 } | |
95 if (mp->m_gname) { | |
96 CHECKMEM (mp->m_gname); | |
97 CPY (mp->m_gname); | |
98 isgroup++; | |
99 } | |
100 sp = adrformat (mp); | |
101 CHECKMEM (sp); | |
102 CPY (sp); | |
103 mnfree (mp); | |
104 } | |
105 | |
106 if (isgroup) | |
107 *dst++ = ';'; | |
108 | |
109 *dst = '\0'; | |
110 last_dst = dst; | |
111 return (buf); | |
112 } |