]> diplodocus.org Git - nmh/blob - docs/historical/mh-jun-1982/progs/replsubs.c
Replaced use of snprintf() with memcpy()/memmove().
[nmh] / docs / historical / mh-jun-1982 / progs / replsubs.c
1 #ifdef COMMENT
2 Proprietary Rand Corporation, 1981.
3 Further distribution of this software
4 subject to the terms of the Rand
5 license agreement.
6 #endif
7
8 #include "../mh.h"
9
10 char *ltrim(cp)
11 char *cp;
12 {
13 /* Return pointer to 1st non-blank char in string;
14 * If ptr ==> 0 or ptr ==> '\n'0, return NUL;
15 */
16
17 register char *cp1;
18
19 cp1 = cp;
20 while((*cp1 == ' ') || (*cp1 == '\t')) cp1++;
21 if((*cp1 == 0) || (*cp1 == '\n' && cp1[1] == 0))
22 cp1 = 0;
23 return(cp1);
24 }
25
26 char *rtrim(cp)
27 char *cp;
28 {
29 /* trim newline and blanks from the right */
30
31 register char *cp1;
32
33 cp1 = cp+strlen(cp)-1;
34 if(*cp1 == '\n') *cp1 = 0;
35 while(*--cp1 == ' ') ;
36 *++cp1 = 0;
37 return(cp);
38 }
39
40 char *niceadd(this, that)
41 char *this, *that;
42 {
43 register char *from, *to;
44
45 if(!(from = ltrim(this))) /* nothing to add */
46 return(that);
47
48 if(to = that)
49 to = add(",\n ", rtrim(to)); /* enuf blanks for "cc: " */
50 return(add(from, to));
51 }
52
53 #define ADDRLEN (needadr ? addrlen : 0)
54
55 char *fix(field, address)
56 char *field, *address;
57 {
58 /* Appends address to each needy addressee in "field".
59 * Returns pointer to copy of new string. (HUH?)
60 * "field" should never be 0
61 */
62
63 register int len;
64 register char *newp;
65 int addrlen;
66 int needadr;
67 int fieldlen;
68 char *cp;
69
70 addrlen = strlen(address);
71 len = 0;
72 newp = "";
73
74 for(cp = field; ;cp += fieldlen + 1) {
75 needadr = needsaddr(&cp, &fieldlen); /* cp may be changed */
76 if(fieldlen == 0) {
77 cndfree(field);
78 newp = add("\n", newp);
79 return(newp);
80 }
81 if((len + fieldlen + ADDRLEN) > 70) {
82 newp = add(",\n ", newp);
83 len = 4;
84 } else if (*newp) {
85 newp = add(", ", newp);
86 len += 2;
87 }
88 *(cp + fieldlen) = 0;
89 newp = add(cp, newp);
90 if(needadr)
91 newp = add(address, newp);
92 len += fieldlen + ADDRLEN;
93 }
94 }
95
96 anychar(fchars, field)
97 char *fchars, *field;
98 {
99 /* Returns 1 if any fancy char appears in "field"
100 * Returns 0 if either "field" is nul or contains no fancy chars
101 */
102
103 register char *fp;
104
105 if(!field)
106 return(0);
107 for(fp = fchars; *fp; fp++)
108 if(r_any(*fp, field))
109 return(1);
110 return(0);
111 }
112
113
114 r_any(chr,stg)
115 char chr, *stg;
116 {
117 register char c, *s;
118
119 c = chr;
120 for (s = stg; (*s) && (*s != ',') && (*s != '\n');)
121 if (*s++ == c) return (1);
122 return (0);
123 }
124
125 char *
126 addr(text)
127 char *text;
128 {
129 static char buf[128];
130 register char *cp, *bufp;
131 int textseen, blankseen;
132 char *copyaddr();
133
134 textseen = blankseen = 0;
135 bufp = buf;
136 if(!text)
137 return(0);
138 for(cp = text; (*cp == ' ' || *cp == '\t'); cp++);
139 for(;;cp++) {
140 switch(*cp) {
141 default:
142 textseen++;
143 break;
144 case ' ': case '\t':
145 blankseen++;
146 break;
147 case 'a':
148 if(!blankseen || !textseen || !ssequal("at ",cp)){
149 textseen++;
150 break;
151 }
152 bufp = copy(" at ", buf);
153 VOID copyaddr(cp+3, bufp);
154 return(buf);
155 case '@':
156 if(!textseen)
157 return(0);
158 bufp = copy(" @ ", buf);
159 VOID copyaddr(cp+1, bufp);
160 return(buf);
161 case ',': case '\n': case 0:
162 return(0);
163 }
164 }
165 }
166
167 #define ND1 (*fp) && (*fp != ' ') && (*fp != '\t')
168 #define ND2 (*fp != '<') && (*fp != '(') && (*fp != '>') && (*fp != ')')
169 #define ND3 (*fp != '\n') && (*fp!= ',') && (*fp != ':')
170 #define NOTDELIM ND1 && ND2 && ND3
171
172 char *copyaddr(fp, tp)
173 register char *fp, *tp;
174 {
175 /* Copies left-trimmed "from" to "to".
176 * Copy terminates on any delimiter.
177 * Returns pointer to NUL terminator in destination string
178 */
179
180 for( ; *fp == ' ' || *fp == '\t'; fp++) ;
181 for( ; NOTDELIM; *tp++ = *fp++);
182 *tp = 0;
183 return(tp);
184 }
185 #define NOTRELEVANT (*cp == ' ' || *cp == '\t' || *cp == '\n'|| *cp == ',')
186
187 needsaddr(field, fieldlen)
188 char **field;
189 int *fieldlen;
190 {
191 /* Returns 1 if this field needs an address
192 * Returns 0 if field contains any funny chars or has
193 * an address of the form "xxxx at " or "xxxx[<b>]@"
194 * "field": on input -- addr of pointer to start of field
195 * on output -- val of ptr moved to 1st meaty char
196 * "fieldlen" returns the length of the new field
197 * (it terminates on ',' or '\n' or 0)
198 */
199
200 register char *cp;
201 int textseen = 0, blankseen = 0;
202 int retval;
203 /* find 1st relevant char in field */
204 for(cp = *field; NOTRELEVANT ; cp++);
205
206 *field = cp; /* return it to caller */
207 if(anychar("(<:", cp)) {
208 retval = 0;
209 goto leave;
210 }
211 for(;;cp++) {
212 switch(*cp) {
213 default:
214 textseen++;
215 break;
216 case ' ': case '\t':
217 blankseen++;
218 break;
219 case 'a':
220 if(!blankseen || !textseen || !ssequal("at ",cp)){
221 textseen++;
222 break;
223 }
224 case '@':
225 retval = 0;
226 goto leave;
227 case ',': case '\n': case 0:
228 retval = 1;
229 goto leave;
230
231 }
232 }
233 leave:
234 for(; (*cp) && (*cp != ',') && (*cp != '\n'); cp++) ;
235 *fieldlen = cp- *field;
236 return(retv