This source file includes following definitions.
- skip_whitespace
- parse_if
- get_qstring
- get_string
- parse
- dump_if
- do_source
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <stdio.h>
22 #include <string.h>
23 #include "tkparse.h"
24
25 struct kconfig * config = NULL;
26 struct kconfig * clast = NULL;
27 struct kconfig * koption = NULL;
28 static int lineno = 0;
29 static int menus_seen = 0;
30 static char * current_file = NULL;
31 static int do_source(char * filename);
32
33
34
35 static char * skip_whitespace(char * pnt)
36 {
37 while( *pnt && (*pnt == ' ' || *pnt == '\t')) pnt++;
38 return pnt;
39 }
40
41
42
43
44
45 static struct condition * parse_if(char * pnt)
46 {
47 char * opnt;
48 struct condition *list;
49 struct condition *last;
50 struct condition *cpnt;
51 char varname[64];
52 char * pnt1;
53
54 opnt = pnt;
55
56
57
58
59 pnt = skip_whitespace(pnt);
60 if( *pnt != '[' ) return NULL;
61 pnt++;
62 pnt = skip_whitespace(pnt);
63
64 list = last = NULL;
65 while(*pnt && *pnt != ']') {
66
67 pnt = skip_whitespace(pnt);
68 if(*pnt== '\0' || *pnt == ']') break;
69
70
71
72
73
74 cpnt = (struct condition *) malloc(sizeof(struct condition));
75 memset(cpnt, 0, sizeof(struct condition));
76 if( last == NULL )
77 {
78 list = last = cpnt;
79 }
80 else
81 {
82 last->next = cpnt;
83 last = cpnt;
84 }
85
86
87
88
89 if( *pnt == '-' && pnt[1] == 'a' )
90 {
91 cpnt->op = op_and;
92 pnt += 2;
93 continue;
94 }
95
96 if( *pnt == '!' && pnt[1] == '=' )
97 {
98 cpnt->op = op_neq;
99 pnt += 2;
100 continue;
101 }
102
103 if( *pnt == '=')
104 {
105 cpnt->op = op_eq;
106 pnt += 1;
107 continue;
108 }
109
110 if( *pnt == '!')
111 {
112 cpnt->op = op_bang;
113 pnt += 1;
114 continue;
115 }
116
117 if( *pnt != '"' ) goto error;
118 pnt++;
119 if( *pnt == '$' )
120 {
121 cpnt->op = op_variable;
122 pnt1 = varname;
123 pnt++;
124 while(*pnt && *pnt != '"') *pnt1++ = *pnt++;
125 *pnt1++ = '\0';
126 cpnt->variable = strdup(varname);
127 if( *pnt == '"' ) pnt++;
128 continue;
129 }
130
131 cpnt->op = op_constant;
132 pnt1 = varname;
133 while(*pnt && *pnt != '"') *pnt1++ = *pnt++;
134 *pnt1++ = '\0';
135 cpnt->variable = strdup(varname);
136 if( *pnt == '"' ) pnt++;
137 continue;
138 }
139
140 return list;
141
142 error:
143 if(current_file != NULL)
144 printf("Bad if clause at line %d(%s):%s\n", lineno, current_file, opnt);
145 else
146 printf("Bad if clause at line %d:%s\n", lineno, opnt);
147 return NULL;
148 }
149
150
151
152
153
154
155
156
157 static char * get_qstring(char *pnt, char ** labl)
158 {
159 char quotechar;
160 char newlabel[1024];
161 char * pnt1;
162 char * pnt2;
163
164 while( *pnt && *pnt != '"' && *pnt != '\'') pnt++;
165 if (*pnt == '\0') return pnt;
166
167 quotechar = *pnt++;
168 pnt1 = newlabel;
169 while(*pnt && *pnt != quotechar && pnt[-1] != '\\')
170 {
171
172
173
174 if( *pnt == '"' || *pnt == '\'' || *pnt == '[' || *pnt == ']')
175 *pnt1++ = '\\';
176
177 *pnt1++ = *pnt++;
178 }
179 *pnt1++ = '\0';
180
181 pnt2 = (char *) malloc(strlen(newlabel) + 1);
182 strcpy(pnt2, newlabel);
183 *labl = pnt2;
184
185
186
187
188 pnt++;
189 pnt = skip_whitespace(pnt);
190 return pnt;
191 }
192
193
194
195
196
197
198
199 static char * get_string(char *pnt, char ** labl)
200 {
201 char quotechar;
202 char newlabel[1024];
203 char * pnt1;
204 char * pnt2;
205
206 if (*pnt == '\0') return pnt;
207
208 pnt1 = newlabel;
209 while(*pnt && *pnt != ' ' && *pnt != '\t')
210 {
211 *pnt1++ = *pnt++;
212 }
213 *pnt1++ = '\0';
214
215 pnt2 = (char *) malloc(strlen(newlabel) + 1);
216 strcpy(pnt2, newlabel);
217 *labl = pnt2;
218
219 if( *pnt ) pnt++;
220 return pnt;
221 }
222
223
224
225
226
227
228
229 int parse(char * pnt) {
230 enum token tok;
231 struct kconfig * kcfg;
232
233
234
235
236 pnt = skip_whitespace(pnt);
237 while( *pnt && (*pnt == ' ' || *pnt == '\t')) pnt++;
238 if(! *pnt ) return;
239 if( *pnt == '#' ) return;
240
241
242
243
244 tok = tok_unknown;
245 if (strncmp(pnt, "mainmenu_name", 13) == 0)
246 {
247 tok = tok_menuname;
248 pnt += 13;
249 }
250 else if (strncmp(pnt, "source", 6) == 0)
251 {
252 pnt += 7;
253 pnt = skip_whitespace(pnt);
254 do_source(pnt);
255 return;
256 }
257 else if (strncmp(pnt, "mainmenu_option", 15) == 0)
258 {
259 menus_seen++;
260 tok = tok_menuoption;
261 pnt += 15;
262 }
263 else if (strncmp(pnt, "comment", 7) == 0)
264 {
265 tok = tok_comment;
266 pnt += 7;
267 }
268 else if (strncmp(pnt, "bool", 4) == 0)
269 {
270 tok = tok_bool;
271 pnt += 4;
272 }
273 else if (strncmp(pnt, "tristate", 8) == 0)
274 {
275 tok = tok_tristate;
276 pnt += 8;
277 }
278 else if (strncmp(pnt, "dep_tristate", 12) == 0)
279 {
280 tok = tok_dep_tristate;
281 pnt += 12;
282 }
283 else if (strncmp(pnt, "int", 3) == 0)
284 {
285 tok = tok_int;
286 pnt += 3;
287 }
288 else if (strncmp(pnt, "if", 2) == 0)
289 {
290 tok = tok_if;
291 pnt += 2;
292 }
293 else if (strncmp(pnt, "else", 4) == 0)
294 {
295 tok = tok_else;
296 pnt += 4;
297 }
298 else if (strncmp(pnt, "fi", 2) == 0)
299 {
300 tok = tok_fi;
301 pnt += 2;
302 }
303
304 if( tok == tok_unknown)
305 {
306 printf("unknown command=%s\n", pnt);
307 return 1;
308 }
309
310
311
312
313
314 kcfg = (struct kconfig *) malloc(sizeof(struct kconfig));
315 memset(kcfg, 0, sizeof(struct kconfig));
316 kcfg->tok = tok;
317 if( clast != NULL )
318 {
319 clast->next = kcfg;
320 clast = kcfg;
321 }
322 else
323 {
324 clast = config = kcfg;
325 }
326
327 pnt = skip_whitespace(pnt);
328
329
330
331
332
333 switch (tok)
334 {
335 case tok_menuname:
336 pnt = get_qstring(pnt, &kcfg->label);
337 break;
338 case tok_bool:
339 case tok_tristate:
340 case tok_int:
341 pnt = get_qstring(pnt, &kcfg->label);
342 pnt = get_string(pnt, &kcfg->optionname);
343 pnt = get_string(pnt, &kcfg->dflt);
344 break;
345 case tok_dep_tristate:
346 pnt = get_qstring(pnt, &kcfg->label);
347 pnt = get_string(pnt, &kcfg->optionname);
348 pnt = get_string(pnt, &kcfg->dflt);
349 pnt = skip_whitespace(pnt);
350 if( *pnt == '$') pnt++;
351 pnt = get_string(pnt, &kcfg->depend.str);
352 break;
353 case tok_comment:
354 pnt = get_qstring(pnt, &kcfg->label);
355 if( koption != NULL )
356 {
357 pnt = get_qstring(pnt, &kcfg->label);
358 koption->label = kcfg->label;
359 koption = NULL;
360 }
361 break;
362 case tok_menuoption:
363 if( strncmp(pnt, "next_comment", 12) == 0)
364 {
365 koption = kcfg;
366 }
367 else
368 {
369 pnt = get_qstring(pnt, &kcfg->label);
370 }
371 break;
372 case tok_else:
373 case tok_fi:
374 break;
375 case tok_if:
376
377
378
379
380 kcfg->cond = parse_if(pnt);
381 if(kcfg->cond == NULL )
382 {
383 exit(1);
384 }
385 break;
386 default:
387 exit(0);
388
389 }
390 }
391
392
393
394
395 dump_if(struct condition * cond)
396 {
397 printf(" ");
398 while(cond != NULL )
399 {
400 switch(cond->op){
401 case op_eq:
402 printf(" = ");
403 break;
404 case op_bang:
405 printf(" ! ");
406 break;
407 case op_neq:
408 printf(" != ");
409 break;
410 case op_and:
411 printf(" -a ");
412 break;
413 case op_lparen:
414 printf("(");
415 break;
416 case op_rparen:
417 printf(")");
418 break;
419 case op_variable:
420 printf("$%s", cond->variable);
421 break;
422 case op_constant:
423 printf("'%s'", cond->variable);
424 break;
425 }
426 cond = cond->next;
427 }
428
429 printf("\n");
430 }
431
432 static int do_source(char * filename)
433 {
434 char buffer[1024];
435 int old_lineno;
436 char * pnt;
437 FILE * infile;
438
439 infile = fopen(filename,"r");
440 if(!infile) {
441 fprintf(stderr,"Unable to open file %s\n", filename);
442 return 1;
443 }
444 old_lineno = lineno;
445 lineno = 0;
446 current_file = filename;
447 while (fgets(buffer, sizeof(buffer), infile))
448 {
449
450
451
452 pnt = buffer + strlen(buffer) - 1;
453 if( *pnt == '\n') *pnt = 0;
454 lineno++;
455 parse(buffer);
456 }
457 fclose(infile);
458 current_file = NULL;
459 lineno = old_lineno;
460 return 0;
461 }
462
463 main(int argc, char * argv[])
464 {
465 char * pnt;
466 struct kconfig * cfg;
467 char buffer[1024];
468 int i;
469
470
471
472
473 while(fgets(buffer, sizeof(buffer), stdin))
474 {
475
476
477
478 pnt = buffer + strlen(buffer) - 1;
479 if( *pnt == '\n') *pnt = 0;
480 lineno++;
481 parse(buffer);
482 }
483
484
485 if( menus_seen == 0 )
486 {
487 fprintf(stderr,"The config.in file for this platform does not support\n");
488 fprintf(stderr,"menus.\n");
489 exit(1);
490 }
491
492
493
494
495
496
497 fix_conditionals(config);
498
499
500
501
502 dump_tk_script(config);
503
504 #if 0
505
506
507
508
509 for(cfg = config; cfg; cfg = cfg->next)
510 {
511
512 if(cfg->cond != NULL && cfg->tok != tok_if)
513 dump_if(cfg->cond);
514
515 switch(cfg->tok)
516 {
517 case tok_menuname:
518 printf("main_menuname ");
519 break;
520 case tok_bool:
521 printf("bool ");
522 break;
523 case tok_tristate:
524 printf("tristate ");
525 break;
526 case tok_dep_tristate:
527 printf("dep_tristate ");
528 break;
529 case tok_int:
530 printf("int ");
531 break;
532 case tok_comment:
533 printf("comment ");
534 break;
535 case tok_menuoption:
536 printf("menuoption ");
537 break;
538 case tok_else:
539 printf("else");
540 break;
541 case tok_fi:
542 printf("fi");
543 break;
544 case tok_if:
545 printf("if");
546 break;
547 default:
548 }
549
550 switch(cfg->tok)
551 {
552 case tok_menuoption:
553 case tok_comment:
554 case tok_menuname:
555 printf("%s\n", cfg->label);
556 break;
557 case tok_bool:
558 case tok_tristate:
559 case tok_dep_tristate:
560 case tok_int:
561 printf("%s %s %s\n", cfg->label, cfg->optionname, cfg->dflt);
562 break;
563 case tok_if:
564 dump_if(cfg->cond);
565 break;
566 case tok_nop:
567 break;
568 default:
569 printf("\n");
570 }
571 }
572 #endif
573
574 return 0;
575
576 }