"Fossies" - the Fresh Open Source Software Archive 
Member "detox-1.4.5/src/config_file_yacc.y" (15 Aug 2021, 8492 Bytes) of package /linux/privat/detox-1.4.5.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Bison source code syntax highlighting (style:
standard) with prefixed line numbers.
Alternatively you can here
view or
download the uninterpreted source code file.
1 %{
2 /**
3 * This file is part of the Detox package.
4 *
5 * Copyright (c) Doug Harple <detox.dharple@gmail.com>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10
11 #include "config.h"
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16
17 #include "detox.h"
18 #include "clean_string.h"
19 #include "config_file.h"
20
21 /*
22 * I must apologize in advance for the cryptic, global variable names.
23 */
24
25 static struct detox_sequence_list *cf_sl_ret, *cf_sl_current;
26 static struct detox_sequence_entry *cf_seq_ret, *cf_seq_current;
27 static struct detox_ignore_entry *cf_ignore_ret, *cf_ignore_current;
28 static struct clean_string_options *csopts;
29 static char *current_name = NULL;
30 static char *current_filename = NULL;
31 static struct detox_options *current_options;
32
33 void cf_append_sequence_list(void);
34 void cf_append_sequence_entry(void *ptr, void *opts);
35 void cf_append_ignore_entry(int token, void *str);
36
37 void yyerror (char *s);
38
39 int yylex (void);
40
41 %}
42
43 %union {
44 char *string; /* string buffer */
45 int cmd; /* command value */
46 struct detox_sequence_entry *seq; /* sequence */
47 int nvalue; /* nvalue */
48 }
49
50 %token <string> QSTRING ID
51 %token <cmd> SEQUENCE IGNORE
52 %token <cmd> UNCGI ISO8859_1 UTF_8 SAFE WIPEUP
53 %token <cmd> MAX_LENGTH LOWER
54 %token <cmd> FILENAME REMOVE_TRAILING LENGTH
55 %token <cmd> OPEN CLOSE EOL
56 %token <nvalue> NVALUE
57
58 %type <string> string
59
60 %%
61
62 configfile:
63 |
64 configfile rule
65 ;
66
67 rule: sequence
68 |
69 ignore
70 ;
71
72 sequence: sequence_open method_list sequence_close
73 ;
74
75 sequence_open: SEQUENCE string OPEN { current_name = $2; }
76 ;
77
78 sequence_close: CLOSE EOL { cf_append_sequence_list(); }
79 ;
80
81 method_list: method |
82 method_list method
83 ;
84
85 method: UNCGI EOL { cf_append_sequence_entry(&clean_uncgi, NULL); }
86 |
87 LOWER EOL { cf_append_sequence_entry(&clean_lower, NULL); }
88 |
89 wipeup EOL
90 |
91 iso8859_1 EOL
92 |
93 utf_8 EOL
94 |
95 safe EOL
96 |
97 max_length EOL
98 ;
99
100 iso8859_1: ISO8859_1 { cf_append_sequence_entry(&clean_iso8859_1, NULL); }
101 |
102 ISO8859_1 OPEN CLOSE { cf_append_sequence_entry(&clean_iso8859_1, NULL); }
103 |
104 ISO8859_1 OPEN FILENAME string EOL CLOSE {
105 csopts = malloc(sizeof(struct clean_string_options));
106 memset(csopts, 0, sizeof(struct clean_string_options));
107 csopts->filename = $4;
108
109 cf_append_sequence_entry(&clean_iso8859_1, csopts);
110 }
111 ;
112
113 utf_8: UTF_8 { cf_append_sequence_entry(&clean_utf_8, NULL); }
114 |
115 UTF_8 OPEN CLOSE { cf_append_sequence_entry(&clean_utf_8, NULL); }
116 |
117 UTF_8 OPEN FILENAME string EOL CLOSE {
118 csopts = malloc(sizeof(struct clean_string_options));
119 memset(csopts, 0, sizeof(struct clean_string_options));
120 csopts->filename = $4;
121
122 cf_append_sequence_entry(&clean_utf_8, csopts);
123 }
124 ;
125
126 safe: SAFE { cf_append_sequence_entry(&clean_safe, NULL); }
127 |
128 SAFE OPEN CLOSE { cf_append_sequence_entry(&clean_safe, NULL); }
129 |
130 SAFE OPEN FILENAME string EOL CLOSE {
131 csopts = malloc(sizeof(struct clean_string_options));
132 memset(csopts, 0, sizeof(struct clean_string_options));
133 csopts->filename = $4;
134
135 cf_append_sequence_entry(&clean_safe, csopts);
136 }
137 ;
138
139 wipeup: WIPEUP {
140 if (current_options->remove_trailing) {
141 csopts = malloc(sizeof(struct clean_string_options));
142 memset(csopts, 0, sizeof(struct clean_string_options));
143 csopts->remove_trailing = 1;
144 }
145 else {
146 csopts = NULL;
147 }
148
149 cf_append_sequence_entry(&clean_wipeup, csopts);
150 }
151 |
152 WIPEUP OPEN CLOSE {
153 if (current_options->remove_trailing) {
154 csopts = malloc(sizeof(struct clean_string_options));
155 memset(csopts, 0, sizeof(struct clean_string_options));
156 csopts->remove_trailing = 1;
157 }
158 else {
159 csopts = NULL;
160 }
161
162 cf_append_sequence_entry(&clean_wipeup, csopts);
163 }
164 |
165 WIPEUP OPEN REMOVE_TRAILING EOL CLOSE {
166 csopts = malloc(sizeof(struct clean_string_options));
167 memset(csopts, 0, sizeof(struct clean_string_options));
168 csopts->remove_trailing = 1;
169
170 cf_append_sequence_entry(&clean_wipeup, csopts);
171 }
172 ;
173
174 max_length: MAX_LENGTH { cf_append_sequence_entry(&clean_max_length, NULL); }
175 |
176 MAX_LENGTH OPEN CLOSE { cf_append_sequence_entry(&clean_max_length, NULL); }
177 |
178 MAX_LENGTH OPEN LENGTH NVALUE EOL CLOSE {
179 csopts = malloc(sizeof(struct clean_string_options));
180 memset(csopts, 0, sizeof(struct clean_string_options));
181 csopts->max_length = (size_t)$4;
182
183 cf_append_sequence_entry(&clean_max_length, csopts);
184 }
185 ;
186
187 ignore: ignore_open ignore_list ignore_close
188 ;
189
190 ignore_open: IGNORE OPEN
191 ;
192
193 ignore_close: CLOSE EOL
194 ;
195
196 ignore_list: ignore_filename |
197 ignore_list ignore_filename
198 ;
199
200 ignore_filename: FILENAME string EOL {
201 cf_append_ignore_entry(FILENAME, $2);
202 }
203 ;
204
205 string: QSTRING { $$ = $1; }
206 |
207 ID { $$ = $1; }
208 ;
209
210 %%
211
212 extern FILE *yyin;
213 extern FILE *yyout;
214
215 struct detox_parse_results *parse_config_file(char *filename, struct detox_parse_results *previous_results, struct detox_options *main_options) {
216 struct detox_parse_results *ret = NULL;
217
218 current_filename = filename;
219 current_options = main_options;
220
221 /*
222 * XXX - Should we be closing the default yyin/yyout? If so, should we
223 * be setting them to NULL at the end of this function?
224 */
225
226 yyin = fopen(filename, "r");
227 if (yyin == NULL) {
228 return previous_results;
229 }
230 yyout = fopen("/dev/null", "w");
231
232 /*
233 * Initialize the return variable
234 */
235
236 if (previous_results) {
237 ret = previous_results;
238 }
239 else {
240 ret = malloc(sizeof(struct detox_parse_results));
241 memset(ret, 0, sizeof(struct detox_parse_results));
242 }
243
244 /*
245 * Initialize the sequence list
246 */
247
248 cf_sl_ret = NULL;
249 cf_sl_current = NULL;
250
251 if (previous_results && previous_results->sequences) {
252 cf_sl_ret = previous_results->sequences;
253 cf_sl_current = cf_sl_ret;
254 while (cf_sl_current->next != NULL) {
255 cf_sl_current = cf_sl_current->next;
256 }
257 }
258
259 /*
260 * Initialize the ignore list
261 */
262
263 cf_ignore_ret = NULL;
264 cf_ignore_current = NULL;
265
266 if (previous_results && previous_results->files_to_ignore) {
267 cf_ignore_ret = previous_results->files_to_ignore;
268 cf_ignore_current = cf_ignore_ret;
269 while (cf_ignore_current->next != NULL) {
270 cf_ignore_current = cf_ignore_current->next;
271 }
272 }
273
274 /*
275 * Reset the sequence entry holding vars
276 */
277
278 cf_seq_ret = NULL;
279 cf_seq_current = NULL;
280
281 do {
282 yyparse();
283 }
284 while (!feof(yyin));
285
286 fclose(yyin);
287 fclose(yyout);
288
289 /*
290 * Populate returns
291 */
292
293 ret->sequences = cf_sl_ret;
294 ret->files_to_ignore = cf_ignore_ret;
295
296 return ret;
297 }
298
299 void yyerror(char *s) {
300 /*
301 * XXX - Is extern valid here? Does it do what I'm expecting?
302 */
303 extern char *yytext;
304
305 fprintf(stderr, "detox: error parsing config file %s: %s\n", current_filename, s);
306 fprintf(stderr, "\tline %d", config_file_lineno);
307 if (yytext != NULL) {
308 fprintf(stderr, ": %s", yytext);
309 }
310 fprintf(stderr, "\n");
311 exit(EXIT_FAILURE);
312 }
313
314
315 void cf_append_sequence_list(void) {
316 struct detox_sequence_list *work;
317
318 if (current_name == NULL) {
319 current_name = strdup("default");
320 }
321
322 work = NULL;
323
324 if (cf_sl_ret != NULL) {
325 work = cf_sl_ret;
326
327 while (work != NULL) {
328 if (strcmp(work->name, current_name) == 0) {
329 break;
330 }
331
332 work = work->next;
333 }
334
335 }
336
337 if (work != NULL) {
338 /*
339 * XXX - Free Old Tree
340 */
341 }
342 else {
343 work = malloc(sizeof(struct detox_sequence_list));
344 memset(work, 0, sizeof(struct detox_sequence_list));
345
346 work->name = strdup(current_name);
347
348 /*
349 * Append to the tree first. If we don't, we could create a
350 * circular reference.
351 */
352 if (cf_sl_ret == NULL) {
353 cf_sl_ret = cf_sl_current = work;
354 }
355 else {
356 cf_sl_current->next = work;
357 cf_sl_current = work;
358 }
359
360 }
361
362 work->head = cf_seq_ret;
363 work->source_filename = strdup(current_filename);
364 cf_seq_ret = cf_seq_current = NULL;
365
366 }
367
368
369 void cf_append_sequence_entry(void *ptr, void *opts) {
370 struct detox_sequence_entry *work;
371
372 work = malloc(sizeof(struct detox_sequence_entry));
373 memset(work, 0, sizeof(struct detox_sequence_entry));
374
375 work->cleaner = ptr;
376 work->options = opts;
377
378 if (cf_seq_ret == NULL) {
379 cf_seq_ret = cf_seq_current = work;
380 }
381 else {
382 cf_seq_current->next = work;
383 cf_seq_current = work;
384 }
385 }
386
387
388 void cf_append_ignore_entry(int token, void *str) {
389 struct detox_ignore_entry *work;
390
391 work = malloc(sizeof(struct detox_ignore_entry));
392 memset(work, 0, sizeof(struct detox_ignore_entry));
393
394 switch(token) {
395 case FILENAME:
396 work->filename = str;
397 break;
398
399 default:
400 break;
401 }
402
403 if (cf_ignore_ret == NULL) {
404 cf_ignore_ret = cf_ignore_current = work;
405 }
406 else {
407 cf_ignore_current->next = work;
408 cf_ignore_current = work;
409 }
410 }
411
412