Blame


1 5cdb1798 2005-10-29 devnull %{
2 5cdb1798 2005-10-29 devnull #include "common.h"
3 5cdb1798 2005-10-29 devnull #include "smtp.h"
4 5cdb1798 2005-10-29 devnull #include <ctype.h>
5 5cdb1798 2005-10-29 devnull
6 5cdb1798 2005-10-29 devnull char *yylp; /* next character to be lex'd */
7 5cdb1798 2005-10-29 devnull int yydone; /* tell yylex to give up */
8 5cdb1798 2005-10-29 devnull char *yybuffer; /* first parsed character */
9 5cdb1798 2005-10-29 devnull char *yyend; /* end of buffer to be parsed */
10 5cdb1798 2005-10-29 devnull Node *root;
11 5cdb1798 2005-10-29 devnull Field *firstfield;
12 5cdb1798 2005-10-29 devnull Field *lastfield;
13 5cdb1798 2005-10-29 devnull Node *usender;
14 5cdb1798 2005-10-29 devnull Node *usys;
15 5cdb1798 2005-10-29 devnull Node *udate;
16 5cdb1798 2005-10-29 devnull char *startfield, *endfield;
17 5cdb1798 2005-10-29 devnull int originator;
18 5cdb1798 2005-10-29 devnull int destination;
19 5cdb1798 2005-10-29 devnull int date;
20 5cdb1798 2005-10-29 devnull int received;
21 5cdb1798 2005-10-29 devnull int messageid;
22 5cdb1798 2005-10-29 devnull %}
23 5cdb1798 2005-10-29 devnull
24 5cdb1798 2005-10-29 devnull %term WORD
25 5cdb1798 2005-10-29 devnull %term DATE
26 5cdb1798 2005-10-29 devnull %term RESENT_DATE
27 5cdb1798 2005-10-29 devnull %term RETURN_PATH
28 5cdb1798 2005-10-29 devnull %term FROM
29 5cdb1798 2005-10-29 devnull %term SENDER
30 5cdb1798 2005-10-29 devnull %term REPLY_TO
31 5cdb1798 2005-10-29 devnull %term RESENT_FROM
32 5cdb1798 2005-10-29 devnull %term RESENT_SENDER
33 5cdb1798 2005-10-29 devnull %term RESENT_REPLY_TO
34 5cdb1798 2005-10-29 devnull %term SUBJECT
35 5cdb1798 2005-10-29 devnull %term TO
36 5cdb1798 2005-10-29 devnull %term CC
37 5cdb1798 2005-10-29 devnull %term BCC
38 5cdb1798 2005-10-29 devnull %term RESENT_TO
39 5cdb1798 2005-10-29 devnull %term RESENT_CC
40 5cdb1798 2005-10-29 devnull %term RESENT_BCC
41 5cdb1798 2005-10-29 devnull %term REMOTE
42 5cdb1798 2005-10-29 devnull %term PRECEDENCE
43 5cdb1798 2005-10-29 devnull %term MIMEVERSION
44 5cdb1798 2005-10-29 devnull %term CONTENTTYPE
45 5cdb1798 2005-10-29 devnull %term MESSAGEID
46 5cdb1798 2005-10-29 devnull %term RECEIVED
47 5cdb1798 2005-10-29 devnull %term MAILER
48 5cdb1798 2005-10-29 devnull %term BADTOKEN
49 5cdb1798 2005-10-29 devnull %start msg
50 5cdb1798 2005-10-29 devnull %%
51 5cdb1798 2005-10-29 devnull
52 5cdb1798 2005-10-29 devnull msg : fields
53 5cdb1798 2005-10-29 devnull | unixfrom '\n' fields
54 5cdb1798 2005-10-29 devnull ;
55 5cdb1798 2005-10-29 devnull fields : '\n'
56 5cdb1798 2005-10-29 devnull { yydone = 1; }
57 5cdb1798 2005-10-29 devnull | field '\n'
58 5cdb1798 2005-10-29 devnull | field '\n' fields
59 5cdb1798 2005-10-29 devnull ;
60 5cdb1798 2005-10-29 devnull field : dates
61 5cdb1798 2005-10-29 devnull { date = 1; }
62 5cdb1798 2005-10-29 devnull | originator
63 5cdb1798 2005-10-29 devnull { originator = 1; }
64 5cdb1798 2005-10-29 devnull | destination
65 5cdb1798 2005-10-29 devnull { destination = 1; }
66 5cdb1798 2005-10-29 devnull | subject
67 5cdb1798 2005-10-29 devnull | optional
68 5cdb1798 2005-10-29 devnull | ignored
69 5cdb1798 2005-10-29 devnull | received
70 5cdb1798 2005-10-29 devnull | precedence
71 5cdb1798 2005-10-29 devnull | error '\n' field
72 5cdb1798 2005-10-29 devnull ;
73 5cdb1798 2005-10-29 devnull unixfrom : FROM route_addr unix_date_time REMOTE FROM word
74 5cdb1798 2005-10-29 devnull { freenode($1); freenode($4); freenode($5);
75 5cdb1798 2005-10-29 devnull usender = $2; udate = $3; usys = $6;
76 5cdb1798 2005-10-29 devnull }
77 5cdb1798 2005-10-29 devnull ;
78 5cdb1798 2005-10-29 devnull originator : REPLY_TO ':' address_list
79 5cdb1798 2005-10-29 devnull { newfield(link3($1, $2, $3), 1); }
80 5cdb1798 2005-10-29 devnull | RETURN_PATH ':' route_addr
81 5cdb1798 2005-10-29 devnull { newfield(link3($1, $2, $3), 1); }
82 5cdb1798 2005-10-29 devnull | FROM ':' mailbox_list
83 5cdb1798 2005-10-29 devnull { newfield(link3($1, $2, $3), 1); }
84 5cdb1798 2005-10-29 devnull | SENDER ':' mailbox
85 5cdb1798 2005-10-29 devnull { newfield(link3($1, $2, $3), 1); }
86 5cdb1798 2005-10-29 devnull | RESENT_REPLY_TO ':' address_list
87 5cdb1798 2005-10-29 devnull { newfield(link3($1, $2, $3), 1); }
88 5cdb1798 2005-10-29 devnull | RESENT_SENDER ':' mailbox
89 5cdb1798 2005-10-29 devnull { newfield(link3($1, $2, $3), 1); }
90 5cdb1798 2005-10-29 devnull | RESENT_FROM ':' mailbox
91 5cdb1798 2005-10-29 devnull { newfield(link3($1, $2, $3), 1); }
92 5cdb1798 2005-10-29 devnull ;
93 5cdb1798 2005-10-29 devnull dates : DATE ':' date_time
94 5cdb1798 2005-10-29 devnull { newfield(link3($1, $2, $3), 0); }
95 5cdb1798 2005-10-29 devnull | RESENT_DATE ':' date_time
96 5cdb1798 2005-10-29 devnull { newfield(link3($1, $2, $3), 0); }
97 5cdb1798 2005-10-29 devnull ;
98 5cdb1798 2005-10-29 devnull destination : TO ':'
99 5cdb1798 2005-10-29 devnull { newfield(link2($1, $2), 0); }
100 5cdb1798 2005-10-29 devnull | TO ':' address_list
101 5cdb1798 2005-10-29 devnull { newfield(link3($1, $2, $3), 0); }
102 5cdb1798 2005-10-29 devnull | RESENT_TO ':'
103 5cdb1798 2005-10-29 devnull { newfield(link2($1, $2), 0); }
104 5cdb1798 2005-10-29 devnull | RESENT_TO ':' address_list
105 5cdb1798 2005-10-29 devnull { newfield(link3($1, $2, $3), 0); }
106 5cdb1798 2005-10-29 devnull | CC ':'
107 5cdb1798 2005-10-29 devnull { newfield(link2($1, $2), 0); }
108 5cdb1798 2005-10-29 devnull | CC ':' address_list
109 5cdb1798 2005-10-29 devnull { newfield(link3($1, $2, $3), 0); }
110 5cdb1798 2005-10-29 devnull | RESENT_CC ':'
111 5cdb1798 2005-10-29 devnull { newfield(link2($1, $2), 0); }
112 5cdb1798 2005-10-29 devnull | RESENT_CC ':' address_list
113 5cdb1798 2005-10-29 devnull { newfield(link3($1, $2, $3), 0); }
114 5cdb1798 2005-10-29 devnull | BCC ':'
115 5cdb1798 2005-10-29 devnull { newfield(link2($1, $2), 0); }
116 5cdb1798 2005-10-29 devnull | BCC ':' address_list
117 5cdb1798 2005-10-29 devnull { newfield(link3($1, $2, $3), 0); }
118 5cdb1798 2005-10-29 devnull | RESENT_BCC ':'
119 5cdb1798 2005-10-29 devnull { newfield(link2($1, $2), 0); }
120 5cdb1798 2005-10-29 devnull | RESENT_BCC ':' address_list
121 5cdb1798 2005-10-29 devnull { newfield(link3($1, $2, $3), 0); }
122 5cdb1798 2005-10-29 devnull ;
123 5cdb1798 2005-10-29 devnull subject : SUBJECT ':' things
124 5cdb1798 2005-10-29 devnull { newfield(link3($1, $2, $3), 0); }
125 5cdb1798 2005-10-29 devnull | SUBJECT ':'
126 5cdb1798 2005-10-29 devnull { newfield(link2($1, $2), 0); }
127 5cdb1798 2005-10-29 devnull ;
128 5cdb1798 2005-10-29 devnull received : RECEIVED ':' things
129 5cdb1798 2005-10-29 devnull { newfield(link3($1, $2, $3), 0); received++; }
130 5cdb1798 2005-10-29 devnull | RECEIVED ':'
131 5cdb1798 2005-10-29 devnull { newfield(link2($1, $2), 0); received++; }
132 5cdb1798 2005-10-29 devnull ;
133 5cdb1798 2005-10-29 devnull precedence : PRECEDENCE ':' things
134 5cdb1798 2005-10-29 devnull { newfield(link3($1, $2, $3), 0); }
135 5cdb1798 2005-10-29 devnull | PRECEDENCE ':'
136 5cdb1798 2005-10-29 devnull { newfield(link2($1, $2), 0); }
137 5cdb1798 2005-10-29 devnull ;
138 5cdb1798 2005-10-29 devnull ignored : ignoredhdr ':' things
139 5cdb1798 2005-10-29 devnull { newfield(link3($1, $2, $3), 0); }
140 5cdb1798 2005-10-29 devnull | ignoredhdr ':'
141 5cdb1798 2005-10-29 devnull { newfield(link2($1, $2), 0); }
142 5cdb1798 2005-10-29 devnull ;
143 5cdb1798 2005-10-29 devnull ignoredhdr : MIMEVERSION | CONTENTTYPE | MESSAGEID { messageid = 1; } | MAILER
144 5cdb1798 2005-10-29 devnull ;
145 5cdb1798 2005-10-29 devnull optional : fieldwords ':' things
146 5cdb1798 2005-10-29 devnull { /* hack to allow same lex for field names and the rest */
147 5cdb1798 2005-10-29 devnull if(badfieldname($1)){
148 5cdb1798 2005-10-29 devnull freenode($1);
149 5cdb1798 2005-10-29 devnull freenode($2);
150 5cdb1798 2005-10-29 devnull freenode($3);
151 5cdb1798 2005-10-29 devnull return 1;
152 5cdb1798 2005-10-29 devnull }
153 5cdb1798 2005-10-29 devnull newfield(link3($1, $2, $3), 0);
154 5cdb1798 2005-10-29 devnull }
155 5cdb1798 2005-10-29 devnull | fieldwords ':'
156 5cdb1798 2005-10-29 devnull { /* hack to allow same lex for field names and the rest */
157 5cdb1798 2005-10-29 devnull if(badfieldname($1)){
158 5cdb1798 2005-10-29 devnull freenode($1);
159 5cdb1798 2005-10-29 devnull freenode($2);
160 5cdb1798 2005-10-29 devnull return 1;
161 5cdb1798 2005-10-29 devnull }
162 5cdb1798 2005-10-29 devnull newfield(link2($1, $2), 0);
163 5cdb1798 2005-10-29 devnull }
164 5cdb1798 2005-10-29 devnull ;
165 5cdb1798 2005-10-29 devnull address_list : address
166 5cdb1798 2005-10-29 devnull | address_list ',' address
167 5cdb1798 2005-10-29 devnull { $$ = link3($1, $2, $3); }
168 5cdb1798 2005-10-29 devnull ;
169 5cdb1798 2005-10-29 devnull address : mailbox
170 5cdb1798 2005-10-29 devnull | group
171 5cdb1798 2005-10-29 devnull ;
172 5cdb1798 2005-10-29 devnull group : phrase ':' address_list ';'
173 5cdb1798 2005-10-29 devnull { $$ = link2($1, link3($2, $3, $4)); }
174 5cdb1798 2005-10-29 devnull | phrase ':' ';'
175 5cdb1798 2005-10-29 devnull { $$ = link3($1, $2, $3); }
176 5cdb1798 2005-10-29 devnull ;
177 5cdb1798 2005-10-29 devnull mailbox_list : mailbox
178 5cdb1798 2005-10-29 devnull | mailbox_list ',' mailbox
179 5cdb1798 2005-10-29 devnull { $$ = link3($1, $2, $3); }
180 5cdb1798 2005-10-29 devnull ;
181 5cdb1798 2005-10-29 devnull mailbox : route_addr
182 5cdb1798 2005-10-29 devnull | phrase brak_addr
183 5cdb1798 2005-10-29 devnull { $$ = link2($1, $2); }
184 5cdb1798 2005-10-29 devnull | brak_addr
185 5cdb1798 2005-10-29 devnull ;
186 5cdb1798 2005-10-29 devnull brak_addr : '<' route_addr '>'
187 5cdb1798 2005-10-29 devnull { $$ = link3($1, $2, $3); }
188 5cdb1798 2005-10-29 devnull | '<' '>'
189 5cdb1798 2005-10-29 devnull { $$ = nobody($2); freenode($1); }
190 5cdb1798 2005-10-29 devnull ;
191 5cdb1798 2005-10-29 devnull route_addr : route ':' at_addr
192 5cdb1798 2005-10-29 devnull { $$ = address(concat($1, concat($2, $3))); }
193 5cdb1798 2005-10-29 devnull | addr_spec
194 5cdb1798 2005-10-29 devnull ;
195 5cdb1798 2005-10-29 devnull route : '@' domain
196 5cdb1798 2005-10-29 devnull { $$ = concat($1, $2); }
197 5cdb1798 2005-10-29 devnull | route ',' '@' domain
198 5cdb1798 2005-10-29 devnull { $$ = concat($1, concat($2, concat($3, $4))); }
199 5cdb1798 2005-10-29 devnull ;
200 5cdb1798 2005-10-29 devnull addr_spec : local_part
201 5cdb1798 2005-10-29 devnull { $$ = address($1); }
202 5cdb1798 2005-10-29 devnull | at_addr
203 5cdb1798 2005-10-29 devnull ;
204 5cdb1798 2005-10-29 devnull at_addr : local_part '@' domain
205 5cdb1798 2005-10-29 devnull { $$ = address(concat($1, concat($2, $3)));}
206 5cdb1798 2005-10-29 devnull | at_addr '@' domain
207 5cdb1798 2005-10-29 devnull { $$ = address(concat($1, concat($2, $3)));}
208 5cdb1798 2005-10-29 devnull ;
209 5cdb1798 2005-10-29 devnull local_part : word
210 5cdb1798 2005-10-29 devnull ;
211 5cdb1798 2005-10-29 devnull domain : word
212 5cdb1798 2005-10-29 devnull ;
213 5cdb1798 2005-10-29 devnull phrase : word
214 5cdb1798 2005-10-29 devnull | phrase word
215 5cdb1798 2005-10-29 devnull { $$ = link2($1, $2); }
216 5cdb1798 2005-10-29 devnull ;
217 5cdb1798 2005-10-29 devnull things : thing
218 5cdb1798 2005-10-29 devnull | things thing
219 5cdb1798 2005-10-29 devnull { $$ = link2($1, $2); }
220 5cdb1798 2005-10-29 devnull ;
221 5cdb1798 2005-10-29 devnull thing : word | '<' | '>' | '@' | ':' | ';' | ','
222 5cdb1798 2005-10-29 devnull ;
223 5cdb1798 2005-10-29 devnull date_time : things
224 5cdb1798 2005-10-29 devnull ;
225 5cdb1798 2005-10-29 devnull unix_date_time : word word word unix_time word word
226 5cdb1798 2005-10-29 devnull { $$ = link3($1, $3, link3($2, $6, link2($4, $5))); }
227 5cdb1798 2005-10-29 devnull ;
228 5cdb1798 2005-10-29 devnull unix_time : word
229 5cdb1798 2005-10-29 devnull | unix_time ':' word
230 5cdb1798 2005-10-29 devnull { $$ = link3($1, $2, $3); }
231 5cdb1798 2005-10-29 devnull ;
232 5cdb1798 2005-10-29 devnull word : WORD | DATE | RESENT_DATE | RETURN_PATH | FROM | SENDER
233 5cdb1798 2005-10-29 devnull | REPLY_TO | RESENT_FROM | RESENT_SENDER | RESENT_REPLY_TO
234 5cdb1798 2005-10-29 devnull | TO | CC | BCC | RESENT_TO | RESENT_CC | RESENT_BCC | REMOTE | SUBJECT
235 5cdb1798 2005-10-29 devnull | PRECEDENCE | MIMEVERSION | CONTENTTYPE | MESSAGEID | RECEIVED | MAILER
236 5cdb1798 2005-10-29 devnull ;
237 5cdb1798 2005-10-29 devnull fieldwords : fieldword
238 5cdb1798 2005-10-29 devnull | WORD
239 5cdb1798 2005-10-29 devnull | fieldwords fieldword
240 5cdb1798 2005-10-29 devnull { $$ = link2($1, $2); }
241 5cdb1798 2005-10-29 devnull | fieldwords word
242 5cdb1798 2005-10-29 devnull { $$ = link2($1, $2); }
243 5cdb1798 2005-10-29 devnull ;
244 5cdb1798 2005-10-29 devnull fieldword : '<' | '>' | '@' | ';' | ','
245 5cdb1798 2005-10-29 devnull ;
246 5cdb1798 2005-10-29 devnull %%
247 5cdb1798 2005-10-29 devnull
248 5cdb1798 2005-10-29 devnull /*
249 5cdb1798 2005-10-29 devnull * Initialize the parsing. Done once for each header field.
250 5cdb1798 2005-10-29 devnull */
251 5cdb1798 2005-10-29 devnull void
252 5cdb1798 2005-10-29 devnull yyinit(char *p, int len)
253 5cdb1798 2005-10-29 devnull {
254 5cdb1798 2005-10-29 devnull yybuffer = p;
255 5cdb1798 2005-10-29 devnull yylp = p;
256 5cdb1798 2005-10-29 devnull yyend = p + len;
257 5cdb1798 2005-10-29 devnull firstfield = lastfield = 0;
258 5cdb1798 2005-10-29 devnull received = 0;
259 5cdb1798 2005-10-29 devnull }
260 5cdb1798 2005-10-29 devnull
261 5cdb1798 2005-10-29 devnull /*
262 5cdb1798 2005-10-29 devnull * keywords identifying header fields we care about
263 5cdb1798 2005-10-29 devnull */
264 5cdb1798 2005-10-29 devnull typedef struct Keyword Keyword;
265 5cdb1798 2005-10-29 devnull struct Keyword {
266 5cdb1798 2005-10-29 devnull char *rep;
267 5cdb1798 2005-10-29 devnull int val;
268 5cdb1798 2005-10-29 devnull };
269 5cdb1798 2005-10-29 devnull
270 5cdb1798 2005-10-29 devnull /* field names that we need to recognize */
271 5cdb1798 2005-10-29 devnull Keyword key[] = {
272 5cdb1798 2005-10-29 devnull { "date", DATE },
273 5cdb1798 2005-10-29 devnull { "resent-date", RESENT_DATE },
274 5cdb1798 2005-10-29 devnull { "return_path", RETURN_PATH },
275 5cdb1798 2005-10-29 devnull { "from", FROM },
276 5cdb1798 2005-10-29 devnull { "sender", SENDER },
277 5cdb1798 2005-10-29 devnull { "reply-to", REPLY_TO },
278 5cdb1798 2005-10-29 devnull { "resent-from", RESENT_FROM },
279 5cdb1798 2005-10-29 devnull { "resent-sender", RESENT_SENDER },
280 5cdb1798 2005-10-29 devnull { "resent-reply-to", RESENT_REPLY_TO },
281 5cdb1798 2005-10-29 devnull { "to", TO },
282 5cdb1798 2005-10-29 devnull { "cc", CC },
283 5cdb1798 2005-10-29 devnull { "bcc", BCC },
284 5cdb1798 2005-10-29 devnull { "resent-to", RESENT_TO },
285 5cdb1798 2005-10-29 devnull { "resent-cc", RESENT_CC },
286 5cdb1798 2005-10-29 devnull { "resent-bcc", RESENT_BCC },
287 5cdb1798 2005-10-29 devnull { "remote", REMOTE },
288 5cdb1798 2005-10-29 devnull { "subject", SUBJECT },
289 5cdb1798 2005-10-29 devnull { "precedence", PRECEDENCE },
290 5cdb1798 2005-10-29 devnull { "mime-version", MIMEVERSION },
291 5cdb1798 2005-10-29 devnull { "content-type", CONTENTTYPE },
292 5cdb1798 2005-10-29 devnull { "message-id", MESSAGEID },
293 5cdb1798 2005-10-29 devnull { "received", RECEIVED },
294 5cdb1798 2005-10-29 devnull { "mailer", MAILER },
295 5cdb1798 2005-10-29 devnull { "who-the-hell-cares", WORD }
296 5cdb1798 2005-10-29 devnull };
297 5cdb1798 2005-10-29 devnull
298 5cdb1798 2005-10-29 devnull /*
299 5cdb1798 2005-10-29 devnull * Lexical analysis for an rfc822 header field. Continuation lines
300 5cdb1798 2005-10-29 devnull * are handled in yywhite() when skipping over white space.
301 5cdb1798 2005-10-29 devnull *
302 5cdb1798 2005-10-29 devnull */
303 5cdb1798 2005-10-29 devnull int
304 5cdb1798 2005-10-29 devnull yylex(void)
305 5cdb1798 2005-10-29 devnull {
306 5cdb1798 2005-10-29 devnull String *t;
307 5cdb1798 2005-10-29 devnull int quoting;
308 5cdb1798 2005-10-29 devnull int escaping;
309 5cdb1798 2005-10-29 devnull char *start;
310 5cdb1798 2005-10-29 devnull Keyword *kp;
311 5cdb1798 2005-10-29 devnull int c, d;
312 5cdb1798 2005-10-29 devnull
313 5cdb1798 2005-10-29 devnull /* print("lexing\n"); /**/
314 5cdb1798 2005-10-29 devnull if(yylp >= yyend)
315 5cdb1798 2005-10-29 devnull return 0;
316 5cdb1798 2005-10-29 devnull if(yydone)
317 5cdb1798 2005-10-29 devnull return 0;
318 5cdb1798 2005-10-29 devnull
319 5cdb1798 2005-10-29 devnull quoting = escaping = 0;
320 5cdb1798 2005-10-29 devnull start = yylp;
321 5cdb1798 2005-10-29 devnull yylval = malloc(sizeof(Node));
322 5cdb1798 2005-10-29 devnull yylval->white = yylval->s = 0;
323 5cdb1798 2005-10-29 devnull yylval->next = 0;
324 5cdb1798 2005-10-29 devnull yylval->addr = 0;
325 5cdb1798 2005-10-29 devnull yylval->start = yylp;
326 5cdb1798 2005-10-29 devnull for(t = 0; yylp < yyend; yylp++){
327 5cdb1798 2005-10-29 devnull c = *yylp & 0xff;
328 5cdb1798 2005-10-29 devnull
329 5cdb1798 2005-10-29 devnull /* dump nulls, they can't be in header */
330 5cdb1798 2005-10-29 devnull if(c == 0)
331 5cdb1798 2005-10-29 devnull continue;
332 5cdb1798 2005-10-29 devnull
333 5cdb1798 2005-10-29 devnull if(escaping) {
334 5cdb1798 2005-10-29 devnull escaping = 0;
335 5cdb1798 2005-10-29 devnull } else if(quoting) {
336 5cdb1798 2005-10-29 devnull switch(c){
337 5cdb1798 2005-10-29 devnull case '\\':
338 5cdb1798 2005-10-29 devnull escaping = 1;
339 5cdb1798 2005-10-29 devnull break;
340 5cdb1798 2005-10-29 devnull case '\n':
341 5cdb1798 2005-10-29 devnull d = (*(yylp+1))&0xff;
342 5cdb1798 2005-10-29 devnull if(d != ' ' && d != '\t'){
343 5cdb1798 2005-10-29 devnull quoting = 0;
344 5cdb1798 2005-10-29 devnull yylp--;
345 5cdb1798 2005-10-29 devnull continue;
346 5cdb1798 2005-10-29 devnull }
347 5cdb1798 2005-10-29 devnull break;
348 5cdb1798 2005-10-29 devnull case '"':
349 5cdb1798 2005-10-29 devnull quoting = 0;
350 5cdb1798 2005-10-29 devnull break;
351 5cdb1798 2005-10-29 devnull }
352 5cdb1798 2005-10-29 devnull } else {
353 5cdb1798 2005-10-29 devnull switch(c){
354 5cdb1798 2005-10-29 devnull case '\\':
355 5cdb1798 2005-10-29 devnull escaping = 1;
356 5cdb1798 2005-10-29 devnull break;
357 5cdb1798 2005-10-29 devnull case '(':
358 5cdb1798 2005-10-29 devnull case ' ':
359 5cdb1798 2005-10-29 devnull case '\t':
360 5cdb1798 2005-10-29 devnull case '\r':
361 5cdb1798 2005-10-29 devnull goto out;
362 5cdb1798 2005-10-29 devnull case '\n':
363 5cdb1798 2005-10-29 devnull if(yylp == start){
364 5cdb1798 2005-10-29 devnull yylp++;
365 5cdb1798 2005-10-29 devnull /* print("lex(c %c)\n", c); /**/
366 5cdb1798 2005-10-29 devnull yylval->end = yylp;
367 5cdb1798 2005-10-29 devnull return yylval->c = c;
368 5cdb1798 2005-10-29 devnull }
369 5cdb1798 2005-10-29 devnull goto out;
370 5cdb1798 2005-10-29 devnull case '@':
371 5cdb1798 2005-10-29 devnull case '>':
372 5cdb1798 2005-10-29 devnull case '<':
373 5cdb1798 2005-10-29 devnull case ':':
374 5cdb1798 2005-10-29 devnull case ',':
375 5cdb1798 2005-10-29 devnull case ';':
376 5cdb1798 2005-10-29 devnull if(yylp == start){
377 5cdb1798 2005-10-29 devnull yylp++;
378 5cdb1798 2005-10-29 devnull yylval->white = yywhite();
379 5cdb1798 2005-10-29 devnull /* print("lex(c %c)\n", c); /**/
380 5cdb1798 2005-10-29 devnull yylval->end = yylp;
381 5cdb1798 2005-10-29 devnull return yylval->c = c;
382 5cdb1798 2005-10-29 devnull }
383 5cdb1798 2005-10-29 devnull goto out;
384 5cdb1798 2005-10-29 devnull case '"':
385 5cdb1798 2005-10-29 devnull quoting = 1;
386 5cdb1798 2005-10-29 devnull break;
387 5cdb1798 2005-10-29 devnull default:
388 5cdb1798 2005-10-29 devnull break;
389 5cdb1798 2005-10-29 devnull }
390 5cdb1798 2005-10-29 devnull }
391 5cdb1798 2005-10-29 devnull if(t == 0)
392 5cdb1798 2005-10-29 devnull t = s_new();
393 5cdb1798 2005-10-29 devnull s_putc(t, c);
394 5cdb1798 2005-10-29 devnull }
395 5cdb1798 2005-10-29 devnull out:
396 5cdb1798 2005-10-29 devnull yylval->white = yywhite();
397 5cdb1798 2005-10-29 devnull if(t) {
398 5cdb1798 2005-10-29 devnull s_terminate(t);
399 5cdb1798 2005-10-29 devnull } else /* message begins with white-space! */
400 5cdb1798 2005-10-29 devnull return yylval->c = '\n';
401 5cdb1798 2005-10-29 devnull yylval->s = t;
402 5cdb1798 2005-10-29 devnull for(kp = key; kp->val != WORD; kp++)
403 5cdb1798 2005-10-29 devnull if(cistrcmp(s_to_c(t), kp->rep)==0)
404 5cdb1798 2005-10-29 devnull break;
405 5cdb1798 2005-10-29 devnull /* print("lex(%d) %s\n", kp->val-WORD, s_to_c(t)); /**/
406 5cdb1798 2005-10-29 devnull yylval->end = yylp;
407 5cdb1798 2005-10-29 devnull return yylval->c = kp->val;
408 5cdb1798 2005-10-29 devnull }
409 5cdb1798 2005-10-29 devnull
410 5cdb1798 2005-10-29 devnull void
411 5cdb1798 2005-10-29 devnull yyerror(char *x)
412 5cdb1798 2005-10-29 devnull {
413 5cdb1798 2005-10-29 devnull USED(x);
414 5cdb1798 2005-10-29 devnull
415 5cdb1798 2005-10-29 devnull /*fprint(2, "parse err: %s\n", x);/**/
416 5cdb1798 2005-10-29 devnull }
417 5cdb1798 2005-10-29 devnull
418 5cdb1798 2005-10-29 devnull /*
419 5cdb1798 2005-10-29 devnull * parse white space and comments
420 5cdb1798 2005-10-29 devnull */
421 5cdb1798 2005-10-29 devnull String *
422 5cdb1798 2005-10-29 devnull yywhite(void)
423 5cdb1798 2005-10-29 devnull {
424 5cdb1798 2005-10-29 devnull String *w;
425 5cdb1798 2005-10-29 devnull int clevel;
426 5cdb1798 2005-10-29 devnull int c;
427 5cdb1798 2005-10-29 devnull int escaping;
428 5cdb1798 2005-10-29 devnull
429 5cdb1798 2005-10-29 devnull escaping = clevel = 0;
430 5cdb1798 2005-10-29 devnull for(w = 0; yylp < yyend; yylp++){
431 5cdb1798 2005-10-29 devnull c = *yylp & 0xff;
432 5cdb1798 2005-10-29 devnull
433 5cdb1798 2005-10-29 devnull /* dump nulls, they can't be in header */
434 5cdb1798 2005-10-29 devnull if(c == 0)
435 5cdb1798 2005-10-29 devnull continue;
436 5cdb1798 2005-10-29 devnull
437 5cdb1798 2005-10-29 devnull if(escaping){
438 5cdb1798 2005-10-29 devnull escaping = 0;
439 5cdb1798 2005-10-29 devnull } else if(clevel) {
440 5cdb1798 2005-10-29 devnull switch(c){
441 5cdb1798 2005-10-29 devnull case '\n':
442 5cdb1798 2005-10-29 devnull /*
443 5cdb1798 2005-10-29 devnull * look for multiline fields
444 5cdb1798 2005-10-29 devnull */
445 5cdb1798 2005-10-29 devnull if(*(yylp+1)==' ' || *(yylp+1)=='\t')
446 5cdb1798 2005-10-29 devnull break;
447 5cdb1798 2005-10-29 devnull else
448 5cdb1798 2005-10-29 devnull goto out;
449 5cdb1798 2005-10-29 devnull case '\\':
450 5cdb1798 2005-10-29 devnull escaping = 1;
451 5cdb1798 2005-10-29 devnull break;
452 5cdb1798 2005-10-29 devnull case '(':
453 5cdb1798 2005-10-29 devnull clevel++;
454 5cdb1798 2005-10-29 devnull break;
455 5cdb1798 2005-10-29 devnull case ')':
456 5cdb1798 2005-10-29 devnull clevel--;
457 5cdb1798 2005-10-29 devnull break;
458 5cdb1798 2005-10-29 devnull }
459 5cdb1798 2005-10-29 devnull } else {
460 5cdb1798 2005-10-29 devnull switch(c){
461 5cdb1798 2005-10-29 devnull case '\\':
462 5cdb1798 2005-10-29 devnull escaping = 1;
463 5cdb1798 2005-10-29 devnull break;
464 5cdb1798 2005-10-29 devnull case '(':
465 5cdb1798 2005-10-29 devnull clevel++;
466 5cdb1798 2005-10-29 devnull break;
467 5cdb1798 2005-10-29 devnull case ' ':
468 5cdb1798 2005-10-29 devnull case '\t':
469 5cdb1798 2005-10-29 devnull case '\r':
470 5cdb1798 2005-10-29 devnull break;
471 5cdb1798 2005-10-29 devnull case '\n':
472 5cdb1798 2005-10-29 devnull /*
473 5cdb1798 2005-10-29 devnull * look for multiline fields
474 5cdb1798 2005-10-29 devnull */
475 5cdb1798 2005-10-29 devnull if(*(yylp+1)==' ' || *(yylp+1)=='\t')
476 5cdb1798 2005-10-29 devnull break;
477 5cdb1798 2005-10-29 devnull else
478 5cdb1798 2005-10-29 devnull goto out;
479 5cdb1798 2005-10-29 devnull default:
480 5cdb1798 2005-10-29 devnull goto out;
481 5cdb1798 2005-10-29 devnull }
482 5cdb1798 2005-10-29 devnull }
483 5cdb1798 2005-10-29 devnull if(w == 0)
484 5cdb1798 2005-10-29 devnull w = s_new();
485 5cdb1798 2005-10-29 devnull s_putc(w, c);
486 5cdb1798 2005-10-29 devnull }
487 5cdb1798 2005-10-29 devnull out:
488 5cdb1798 2005-10-29 devnull if(w)
489 5cdb1798 2005-10-29 devnull s_terminate(w);
490 5cdb1798 2005-10-29 devnull return w;
491 5cdb1798 2005-10-29 devnull }
492 5cdb1798 2005-10-29 devnull
493 5cdb1798 2005-10-29 devnull /*
494 5cdb1798 2005-10-29 devnull * link two parsed entries together
495 5cdb1798 2005-10-29 devnull */
496 5cdb1798 2005-10-29 devnull Node*
497 5cdb1798 2005-10-29 devnull link2(Node *p1, Node *p2)
498 5cdb1798 2005-10-29 devnull {
499 5cdb1798 2005-10-29 devnull Node *p;
500 5cdb1798 2005-10-29 devnull
501 5cdb1798 2005-10-29 devnull for(p = p1; p->next; p = p->next)
502 5cdb1798 2005-10-29 devnull ;
503 5cdb1798 2005-10-29 devnull p->next = p2;
504 5cdb1798 2005-10-29 devnull return p1;
505 5cdb1798 2005-10-29 devnull }
506 5cdb1798 2005-10-29 devnull
507 5cdb1798 2005-10-29 devnull /*
508 5cdb1798 2005-10-29 devnull * link three parsed entries together
509 5cdb1798 2005-10-29 devnull */
510 5cdb1798 2005-10-29 devnull Node*
511 5cdb1798 2005-10-29 devnull link3(Node *p1, Node *p2, Node *p3)
512 5cdb1798 2005-10-29 devnull {
513 5cdb1798 2005-10-29 devnull Node *p;
514 5cdb1798 2005-10-29 devnull
515 5cdb1798 2005-10-29 devnull for(p = p2; p->next; p = p->next)
516 5cdb1798 2005-10-29 devnull ;
517 5cdb1798 2005-10-29 devnull p->next = p3;
518 5cdb1798 2005-10-29 devnull
519 5cdb1798 2005-10-29 devnull for(p = p1; p->next; p = p->next)
520 5cdb1798 2005-10-29 devnull ;
521 5cdb1798 2005-10-29 devnull p->next = p2;
522 5cdb1798 2005-10-29 devnull
523 5cdb1798 2005-10-29 devnull return p1;
524 5cdb1798 2005-10-29 devnull }
525 5cdb1798 2005-10-29 devnull
526 5cdb1798 2005-10-29 devnull /*
527 5cdb1798 2005-10-29 devnull * make a:b, move all white space after both
528 5cdb1798 2005-10-29 devnull */
529 5cdb1798 2005-10-29 devnull Node*
530 5cdb1798 2005-10-29 devnull colon(Node *p1, Node *p2)
531 5cdb1798 2005-10-29 devnull {
532 5cdb1798 2005-10-29 devnull if(p1->white){
533 5cdb1798 2005-10-29 devnull if(p2->white)
534 5cdb1798 2005-10-29 devnull s_append(p1->white, s_to_c(p2->white));
535 5cdb1798 2005-10-29 devnull } else {
536 5cdb1798 2005-10-29 devnull p1->white = p2->white;
537 5cdb1798 2005-10-29 devnull p2->white = 0;
538 5cdb1798 2005-10-29 devnull }
539 5cdb1798 2005-10-29 devnull
540 5cdb1798 2005-10-29 devnull s_append(p1->s, ":");
541 5cdb1798 2005-10-29 devnull if(p2->s)
542 5cdb1798 2005-10-29 devnull s_append(p1->s, s_to_c(p2->s));
543 5cdb1798 2005-10-29 devnull
544 5cdb1798 2005-10-29 devnull if(p1->end < p2->end)
545 5cdb1798 2005-10-29 devnull p1->end = p2->end;
546 5cdb1798 2005-10-29 devnull freenode(p2);
547 5cdb1798 2005-10-29 devnull return p1;
548 5cdb1798 2005-10-29 devnull }
549 5cdb1798 2005-10-29 devnull
550 5cdb1798 2005-10-29 devnull /*
551 5cdb1798 2005-10-29 devnull * concatenate two fields, move all white space after both
552 5cdb1798 2005-10-29 devnull */
553 5cdb1798 2005-10-29 devnull Node*
554 5cdb1798 2005-10-29 devnull concat(Node *p1, Node *p2)
555 5cdb1798 2005-10-29 devnull {
556 5cdb1798 2005-10-29 devnull char buf[2];
557 5cdb1798 2005-10-29 devnull
558 5cdb1798 2005-10-29 devnull if(p1->white){
559 5cdb1798 2005-10-29 devnull if(p2->white)
560 5cdb1798 2005-10-29 devnull s_append(p1->white, s_to_c(p2->white));
561 5cdb1798 2005-10-29 devnull } else {
562 5cdb1798 2005-10-29 devnull p1->white = p2->white;
563 5cdb1798 2005-10-29 devnull p2->white = 0;
564 5cdb1798 2005-10-29 devnull }
565 5cdb1798 2005-10-29 devnull
566 5cdb1798 2005-10-29 devnull if(p1->s == nil){
567 5cdb1798 2005-10-29 devnull buf[0] = p1->c;
568 5cdb1798 2005-10-29 devnull buf[1] = 0;
569 5cdb1798 2005-10-29 devnull p1->s = s_new();
570 5cdb1798 2005-10-29 devnull s_append(p1->s, buf);
571 5cdb1798 2005-10-29 devnull }
572 5cdb1798 2005-10-29 devnull
573 5cdb1798 2005-10-29 devnull if(p2->s)
574 5cdb1798 2005-10-29 devnull s_append(p1->s, s_to_c(p2->s));
575 5cdb1798 2005-10-29 devnull else {
576 5cdb1798 2005-10-29 devnull buf[0] = p2->c;
577 5cdb1798 2005-10-29 devnull buf[1] = 0;
578 5cdb1798 2005-10-29 devnull s_append(p1->s, buf);
579 5cdb1798 2005-10-29 devnull }
580 5cdb1798 2005-10-29 devnull
581 5cdb1798 2005-10-29 devnull if(p1->end < p2->end)
582 5cdb1798 2005-10-29 devnull p1->end = p2->end;
583 5cdb1798 2005-10-29 devnull freenode(p2);
584 5cdb1798 2005-10-29 devnull return p1;
585 5cdb1798 2005-10-29 devnull }
586 5cdb1798 2005-10-29 devnull
587 5cdb1798 2005-10-29 devnull /*
588 5cdb1798 2005-10-29 devnull * look for disallowed chars in the field name
589 5cdb1798 2005-10-29 devnull */
590 5cdb1798 2005-10-29 devnull int
591 5cdb1798 2005-10-29 devnull badfieldname(Node *p)
592 5cdb1798 2005-10-29 devnull {
593 5cdb1798 2005-10-29 devnull for(; p; p = p->next){
594 5cdb1798 2005-10-29 devnull /* field name can't contain white space */
595 5cdb1798 2005-10-29 devnull if(p->white && p->next)
596 5cdb1798 2005-10-29 devnull return 1;
597 5cdb1798 2005-10-29 devnull }
598 5cdb1798 2005-10-29 devnull return 0;
599 5cdb1798 2005-10-29 devnull }
600 5cdb1798 2005-10-29 devnull
601 5cdb1798 2005-10-29 devnull /*
602 5cdb1798 2005-10-29 devnull * mark as an address
603 5cdb1798 2005-10-29 devnull */
604 5cdb1798 2005-10-29 devnull Node *
605 5cdb1798 2005-10-29 devnull address(Node *p)
606 5cdb1798 2005-10-29 devnull {
607 5cdb1798 2005-10-29 devnull p->addr = 1;
608 5cdb1798 2005-10-29 devnull return p;
609 5cdb1798 2005-10-29 devnull }
610 5cdb1798 2005-10-29 devnull
611 5cdb1798 2005-10-29 devnull /*
612 5cdb1798 2005-10-29 devnull * case independent string compare
613 5cdb1798 2005-10-29 devnull */
614 5cdb1798 2005-10-29 devnull int
615 5cdb1798 2005-10-29 devnull cistrcmp(char *s1, char *s2)
616 5cdb1798 2005-10-29 devnull {
617 5cdb1798 2005-10-29 devnull int c1, c2;
618 5cdb1798 2005-10-29 devnull
619 5cdb1798 2005-10-29 devnull for(; *s1; s1++, s2++){
620 5cdb1798 2005-10-29 devnull c1 = isupper(*s1) ? tolower(*s1) : *s1;
621 5cdb1798 2005-10-29 devnull c2 = isupper(*s2) ? tolower(*s2) : *s2;
622 5cdb1798 2005-10-29 devnull if (c1 != c2)
623 5cdb1798 2005-10-29 devnull return -1;
624 5cdb1798 2005-10-29 devnull }
625 5cdb1798 2005-10-29 devnull return *s2;
626 5cdb1798 2005-10-29 devnull }
627 5cdb1798 2005-10-29 devnull
628 5cdb1798 2005-10-29 devnull /*
629 5cdb1798 2005-10-29 devnull * free a node
630 5cdb1798 2005-10-29 devnull */
631 5cdb1798 2005-10-29 devnull void
632 5cdb1798 2005-10-29 devnull freenode(Node *p)
633 5cdb1798 2005-10-29 devnull {
634 5cdb1798 2005-10-29 devnull Node *tp;
635 5cdb1798 2005-10-29 devnull
636 5cdb1798 2005-10-29 devnull while(p){
637 5cdb1798 2005-10-29 devnull tp = p->next;
638 5cdb1798 2005-10-29 devnull if(p->s)
639 5cdb1798 2005-10-29 devnull s_free(p->s);
640 5cdb1798 2005-10-29 devnull if(p->white)
641 5cdb1798 2005-10-29 devnull s_free(p->white);
642 5cdb1798 2005-10-29 devnull free(p);
643 5cdb1798 2005-10-29 devnull p = tp;
644 5cdb1798 2005-10-29 devnull }
645 5cdb1798 2005-10-29 devnull }
646 5cdb1798 2005-10-29 devnull
647 5cdb1798 2005-10-29 devnull
648 5cdb1798 2005-10-29 devnull /*
649 5cdb1798 2005-10-29 devnull * an anonymous user
650 5cdb1798 2005-10-29 devnull */
651 5cdb1798 2005-10-29 devnull Node*
652 5cdb1798 2005-10-29 devnull nobody(Node *p)
653 5cdb1798 2005-10-29 devnull {
654 5cdb1798 2005-10-29 devnull if(p->s)
655 5cdb1798 2005-10-29 devnull s_free(p->s);
656 5cdb1798 2005-10-29 devnull p->s = s_copy("pOsTmAsTeR");
657 5cdb1798 2005-10-29 devnull p->addr = 1;
658 5cdb1798 2005-10-29 devnull return p;
659 5cdb1798 2005-10-29 devnull }
660 5cdb1798 2005-10-29 devnull
661 5cdb1798 2005-10-29 devnull /*
662 5cdb1798 2005-10-29 devnull * add anything that was dropped because of a parse error
663 5cdb1798 2005-10-29 devnull */
664 5cdb1798 2005-10-29 devnull void
665 5cdb1798 2005-10-29 devnull missing(Node *p)
666 5cdb1798 2005-10-29 devnull {
667 5cdb1798 2005-10-29 devnull Node *np;
668 5cdb1798 2005-10-29 devnull char *start, *end;
669 5cdb1798 2005-10-29 devnull Field *f;
670 5cdb1798 2005-10-29 devnull String *s;
671 5cdb1798 2005-10-29 devnull
672 5cdb1798 2005-10-29 devnull start = yybuffer;
673 5cdb1798 2005-10-29 devnull if(lastfield != nil){
674 5cdb1798 2005-10-29 devnull for(np = lastfield->node; np; np = np->next)
675 5cdb1798 2005-10-29 devnull start = np->end+1;
676 5cdb1798 2005-10-29 devnull }
677 5cdb1798 2005-10-29 devnull
678 5cdb1798 2005-10-29 devnull end = p->start-1;
679 5cdb1798 2005-10-29 devnull
680 5cdb1798 2005-10-29 devnull if(end <= start)
681 5cdb1798 2005-10-29 devnull return;
682 5cdb1798 2005-10-29 devnull
683 5cdb1798 2005-10-29 devnull if(strncmp(start, "From ", 5) == 0)
684 5cdb1798 2005-10-29 devnull return;
685 5cdb1798 2005-10-29 devnull
686 5cdb1798 2005-10-29 devnull np = malloc(sizeof(Node));
687 5cdb1798 2005-10-29 devnull np->start = start;
688 5cdb1798 2005-10-29 devnull np->end = end;
689 5cdb1798 2005-10-29 devnull np->white = nil;
690 5cdb1798 2005-10-29 devnull s = s_copy("BadHeader: ");
691 5cdb1798 2005-10-29 devnull np->s = s_nappend(s, start, end-start);
692 5cdb1798 2005-10-29 devnull np->next = nil;
693 5cdb1798 2005-10-29 devnull
694 5cdb1798 2005-10-29 devnull f = malloc(sizeof(Field));
695 5cdb1798 2005-10-29 devnull f->next = 0;
696 5cdb1798 2005-10-29 devnull f->node = np;
697 5cdb1798 2005-10-29 devnull f->source = 0;
698 5cdb1798 2005-10-29 devnull if(firstfield)
699 5cdb1798 2005-10-29 devnull lastfield->next = f;
700 5cdb1798 2005-10-29 devnull else
701 5cdb1798 2005-10-29 devnull firstfield = f;
702 5cdb1798 2005-10-29 devnull lastfield = f;
703 5cdb1798 2005-10-29 devnull }
704 5cdb1798 2005-10-29 devnull
705 5cdb1798 2005-10-29 devnull /*
706 5cdb1798 2005-10-29 devnull * create a new field
707 5cdb1798 2005-10-29 devnull */
708 5cdb1798 2005-10-29 devnull void
709 5cdb1798 2005-10-29 devnull newfield(Node *p, int source)
710 5cdb1798 2005-10-29 devnull {
711 5cdb1798 2005-10-29 devnull Field *f;
712 5cdb1798 2005-10-29 devnull
713 5cdb1798 2005-10-29 devnull missing(p);
714 5cdb1798 2005-10-29 devnull
715 5cdb1798 2005-10-29 devnull f = malloc(sizeof(Field));
716 5cdb1798 2005-10-29 devnull f->next = 0;
717 5cdb1798 2005-10-29 devnull f->node = p;
718 5cdb1798 2005-10-29 devnull f->source = source;
719 5cdb1798 2005-10-29 devnull if(firstfield)
720 5cdb1798 2005-10-29 devnull lastfield->next = f;
721 5cdb1798 2005-10-29 devnull else
722 5cdb1798 2005-10-29 devnull firstfield = f;
723 5cdb1798 2005-10-29 devnull lastfield = f;
724 5cdb1798 2005-10-29 devnull endfield = startfield;
725 5cdb1798 2005-10-29 devnull startfield = yylp;
726 5cdb1798 2005-10-29 devnull }
727 5cdb1798 2005-10-29 devnull
728 5cdb1798 2005-10-29 devnull /*
729 5cdb1798 2005-10-29 devnull * fee a list of fields
730 5cdb1798 2005-10-29 devnull */
731 5cdb1798 2005-10-29 devnull void
732 5cdb1798 2005-10-29 devnull freefield(Field *f)
733 5cdb1798 2005-10-29 devnull {
734 5cdb1798 2005-10-29 devnull Field *tf;
735 5cdb1798 2005-10-29 devnull
736 5cdb1798 2005-10-29 devnull while(f){
737 5cdb1798 2005-10-29 devnull tf = f->next;
738 5cdb1798 2005-10-29 devnull freenode(f->node);
739 5cdb1798 2005-10-29 devnull free(f);
740 5cdb1798 2005-10-29 devnull f = tf;
741 5cdb1798 2005-10-29 devnull }
742 5cdb1798 2005-10-29 devnull }
743 5cdb1798 2005-10-29 devnull
744 5cdb1798 2005-10-29 devnull /*
745 5cdb1798 2005-10-29 devnull * add some white space to a node
746 5cdb1798 2005-10-29 devnull */
747 5cdb1798 2005-10-29 devnull Node*
748 5cdb1798 2005-10-29 devnull whiten(Node *p)
749 5cdb1798 2005-10-29 devnull {
750 5cdb1798 2005-10-29 devnull Node *tp;
751 5cdb1798 2005-10-29 devnull
752 5cdb1798 2005-10-29 devnull for(tp = p; tp->next; tp = tp->next)
753 5cdb1798 2005-10-29 devnull ;
754 5cdb1798 2005-10-29 devnull if(tp->white == 0)
755 5cdb1798 2005-10-29 devnull tp->white = s_copy(" ");
756 5cdb1798 2005-10-29 devnull return p;
757 5cdb1798 2005-10-29 devnull }
758 5cdb1798 2005-10-29 devnull
759 5cdb1798 2005-10-29 devnull void
760 5cdb1798 2005-10-29 devnull yycleanup(void)
761 5cdb1798 2005-10-29 devnull {
762 5cdb1798 2005-10-29 devnull Field *f, *fnext;
763 5cdb1798 2005-10-29 devnull Node *np, *next;
764 5cdb1798 2005-10-29 devnull
765 5cdb1798 2005-10-29 devnull for(f = firstfield; f; f = fnext){
766 5cdb1798 2005-10-29 devnull for(np = f->node; np; np = next){
767 5cdb1798 2005-10-29 devnull if(np->s)
768 5cdb1798 2005-10-29 devnull s_free(np->s);
769 5cdb1798 2005-10-29 devnull if(np->white)
770 5cdb1798 2005-10-29 devnull s_free(np->white);
771 5cdb1798 2005-10-29 devnull next = np->next;
772 5cdb1798 2005-10-29 devnull free(np);
773 5cdb1798 2005-10-29 devnull }
774 5cdb1798 2005-10-29 devnull fnext = f->next;
775 5cdb1798 2005-10-29 devnull free(f);
776 5cdb1798 2005-10-29 devnull }
777 5cdb1798 2005-10-29 devnull firstfield = lastfield = 0;
778 5cdb1798 2005-10-29 devnull }