This source file includes following definitions.
- skip_whitespace
- parse_if
- get_qstring
- parse_choices
- 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 <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include "tkparse.h"
25
26 struct kconfig * config = NULL;
27 struct kconfig * clast = NULL;
28 struct kconfig * koption = NULL;
29 static int lineno = 0;
30 static int menus_seen = 0;
31 static char * current_file = NULL;
32 static int do_source(char * filename);
33 static char * get_string(char *pnt, char ** labl);
34 static int choose_number = 0;
35
36
37
38
39
40 static char * skip_whitespace(char * pnt)
41 {
42 while( *pnt && (*pnt == ' ' || *pnt == '\t')) pnt++;
43 return pnt;
44 }
45
46
47
48
49
50 static struct condition * parse_if(char * pnt)
51 {
52 char * opnt;
53 struct condition *list;
54 struct condition *last;
55 struct condition *cpnt;
56 char varname[64];
57 char * pnt1;
58
59 opnt = pnt;
60
61
62
63
64 pnt = skip_whitespace(pnt);
65 if( *pnt != '[' ) return NULL;
66 pnt++;
67 pnt = skip_whitespace(pnt);
68
69 list = last = NULL;
70 while(*pnt && *pnt != ']') {
71
72 pnt = skip_whitespace(pnt);
73 if(*pnt== '\0' || *pnt == ']') break;
74
75
76
77
78
79 cpnt = (struct condition *) malloc(sizeof(struct condition));
80 memset(cpnt, 0, sizeof(struct condition));
81 if( last == NULL )
82 {
83 list = last = cpnt;
84 }
85 else
86 {
87 last->next = cpnt;
88 last = cpnt;
89 }
90
91
92
93
94 if( *pnt == '-' && pnt[1] == 'a' )
95 {
96 cpnt->op = op_and;
97 pnt += 2;
98 continue;
99 }
100
101 if( *pnt == '-' && pnt[1] == 'o' )
102 {
103 cpnt->op = op_or;
104 pnt += 2;
105 continue;
106 }
107
108 if( *pnt == '!' && pnt[1] == '=' )
109 {
110 cpnt->op = op_neq;
111 pnt += 2;
112 continue;
113 }
114
115 if( *pnt == '=')
116 {
117 cpnt->op = op_eq;
118 pnt += 1;
119 continue;
120 }
121
122 if( *pnt == '!')
123 {
124 cpnt->op = op_bang;
125 pnt += 1;
126 continue;
127 }
128
129 if( *pnt != '"' ) goto error;
130 pnt++;
131 if( *pnt == '`' )
132 {
133 cpnt->op = op_shellcmd;
134 pnt1 = varname;
135 pnt++;
136 while(*pnt && *pnt != '`') *pnt1++ = *pnt++;
137 *pnt1++ = '\0';
138 cpnt->variable = strdup(varname);
139 if( *pnt == '`' ) pnt++;
140 if( *pnt == '"' ) pnt++;
141 continue;
142 }
143 if( *pnt == '$' )
144 {
145 cpnt->op = op_variable;
146 pnt1 = varname;
147 pnt++;
148 while(*pnt && *pnt != '"') *pnt1++ = *pnt++;
149 *pnt1++ = '\0';
150 cpnt->variable = strdup(varname);
151 if( *pnt == '"' ) pnt++;
152 continue;
153 }
154
155 cpnt->op = op_constant;
156 pnt1 = varname;
157 while(*pnt && *pnt != '"') *pnt1++ = *pnt++;
158 *pnt1++ = '\0';
159 cpnt->variable = strdup(varname);
160 if( *pnt == '"' ) pnt++;
161 continue;
162 }
163
164 return list;
165
166 error:
167 if(current_file != NULL)
168 fprintf(stderr,
169 "Bad if clause at line %d(%s):%s\n", lineno, current_file, opnt);
170 else
171 fprintf(stderr,
172 "Bad if clause at line %d:%s\n", lineno, opnt);
173 return NULL;
174 }
175
176
177
178
179
180
181
182
183 static char * get_qstring(char *pnt, char ** labl)
184 {
185 char quotechar;
186 char newlabel[1024];
187 char * pnt1;
188 char * pnt2;
189
190 while( *pnt && *pnt != '"' && *pnt != '\'') pnt++;
191 if (*pnt == '\0') return pnt;
192
193 quotechar = *pnt++;
194 pnt1 = newlabel;
195 while(*pnt && *pnt != quotechar && pnt[-1] != '\\')
196 {
197
198
199
200 if( *pnt == '"' || *pnt == '\'' || *pnt == '[' || *pnt == ']')
201 *pnt1++ = '\\';
202
203 *pnt1++ = *pnt++;
204 }
205 *pnt1++ = '\0';
206
207 pnt2 = (char *) malloc(strlen(newlabel) + 1);
208 strcpy(pnt2, newlabel);
209 *labl = pnt2;
210
211
212
213
214 pnt++;
215 pnt = skip_whitespace(pnt);
216 return pnt;
217 }
218
219 static char * parse_choices(struct kconfig * choice_kcfg, char * pnt)
220 {
221 struct kconfig * kcfg;
222 int index = 1;
223
224
225
226
227 while(1)
228 {
229 pnt = skip_whitespace(pnt);
230 if(*pnt == '\0') break;
231
232 kcfg = (struct kconfig *) malloc(sizeof(struct kconfig));
233 memset(kcfg, 0, sizeof(struct kconfig));
234 kcfg->tok = tok_choice;
235 if( clast != NULL )
236 {
237 clast->next = kcfg;
238 clast = kcfg;
239 }
240 else
241 {
242 clast = config = kcfg;
243 }
244
245 pnt = get_string(pnt, &kcfg->label);
246 pnt = skip_whitespace(pnt);
247 pnt = get_string(pnt, &kcfg->optionname);
248 kcfg->choice_label = choice_kcfg;
249 kcfg->choice_value = index++;
250 if( strcmp(kcfg->label, choice_kcfg->value) == 0 )
251 choice_kcfg->choice_value = kcfg->choice_value;
252 }
253
254 return pnt;
255 }
256
257
258
259
260
261
262
263
264 static char * get_string(char *pnt, char ** labl)
265 {
266 char newlabel[1024];
267 char * pnt1;
268 char * pnt2;
269
270 if (*pnt == '\0') return pnt;
271
272 pnt1 = newlabel;
273 while(*pnt && *pnt != ' ' && *pnt != '\t')
274 {
275 *pnt1++ = *pnt++;
276 }
277 *pnt1++ = '\0';
278
279 pnt2 = (char *) malloc(strlen(newlabel) + 1);
280 strcpy(pnt2, newlabel);
281 *labl = pnt2;
282
283 if( *pnt ) pnt++;
284 return pnt;
285 }
286
287
288
289
290
291
292
293 void parse(char * pnt) {
294 enum token tok;
295 struct kconfig * kcfg;
296 char tmpbuf[24],fake_if[1024];
297
298
299
300
301
302 pnt = skip_whitespace(pnt);
303 while( *pnt && (*pnt == ' ' || *pnt == '\t')) pnt++;
304 if(! *pnt ) return;
305 if( *pnt == '#' ) return;
306
307
308
309
310 tok = tok_unknown;
311 if (strncmp(pnt, "mainmenu_name", 13) == 0)
312 {
313 tok = tok_menuname;
314 pnt += 13;
315 }
316 else if (strncmp(pnt, "source", 6) == 0)
317 {
318 pnt += 7;
319 pnt = skip_whitespace(pnt);
320 do_source(pnt);
321 return;
322 }
323 else if (strncmp(pnt, "mainmenu_option", 15) == 0)
324 {
325 menus_seen++;
326 tok = tok_menuoption;
327 pnt += 15;
328 }
329 else if (strncmp(pnt, "$MAKE -C drivers/sound", 22) == 0)
330 {
331 pnt += 22;
332 tok = tok_sound;
333 }
334 else if (strncmp(pnt, "comment", 7) == 0)
335 {
336 tok = tok_comment;
337 pnt += 7;
338 }
339 else if (strncmp(pnt, "choice", 6) == 0)
340 {
341 tok = tok_choose;
342 pnt += 6;
343 }
344 else if (strncmp(pnt, "define_bool", 11) == 0)
345 {
346 tok = tok_define;
347 pnt += 11;
348 }
349 else if (strncmp(pnt, "bool", 4) == 0)
350 {
351 tok = tok_bool;
352 pnt += 4;
353 }
354 else if (strncmp(pnt, "tristate", 8) == 0)
355 {
356 tok = tok_tristate;
357 pnt += 8;
358 }
359 else if (strncmp(pnt, "dep_tristate", 12) == 0)
360 {
361 tok = tok_dep_tristate;
362 pnt += 12;
363 }
364 else if (strncmp(pnt, "int", 3) == 0)
365 {
366 tok = tok_int;
367 pnt += 3;
368 }
369 else if (strncmp(pnt, "hex", 3) == 0)
370 {
371 tok = tok_hex;
372 pnt += 3;
373 }
374 else if (strncmp(pnt, "if", 2) == 0)
375 {
376 tok = tok_if;
377 pnt += 2;
378 }
379 else if (strncmp(pnt, "else", 4) == 0)
380 {
381 tok = tok_else;
382 pnt += 4;
383 }
384 else if (strncmp(pnt, "fi", 2) == 0)
385 {
386 tok = tok_fi;
387 pnt += 2;
388 }
389 else if (strncmp(pnt, "endmenu", 7) == 0)
390 {
391 tok = tok_endmenu;
392 pnt += 7;
393 }
394
395 if( tok == tok_unknown)
396 {
397 if( clast != NULL && clast->tok == tok_if
398 && strcmp(pnt,"then") == 0) return;
399 if( current_file != NULL )
400 fprintf(stderr, "unknown command=%s(%s %d)\n", pnt,
401 current_file, lineno);
402 else
403 fprintf(stderr, "unknown command=%s(%d)\n", pnt,lineno);
404 return;
405 }
406
407
408
409
410
411 kcfg = (struct kconfig *) malloc(sizeof(struct kconfig));
412 memset(kcfg, 0, sizeof(struct kconfig));
413 kcfg->tok = tok;
414 if( clast != NULL )
415 {
416 clast->next = kcfg;
417 clast = kcfg;
418 }
419 else
420 {
421 clast = config = kcfg;
422 }
423
424 pnt = skip_whitespace(pnt);
425
426
427
428
429
430 switch (tok)
431 {
432 case tok_choose:
433 pnt = get_qstring(pnt, &kcfg->label);
434 pnt = get_qstring(pnt, &kcfg->optionname);
435 pnt = get_string(pnt, &kcfg->value);
436
437
438
439
440 parse_choices(kcfg, kcfg->optionname);
441 free(kcfg->optionname);
442 sprintf(tmpbuf, "tmpvar_%d", choose_number++);
443 kcfg->optionname = strdup(tmpbuf);
444 break;
445 case tok_define:
446 pnt = get_string(pnt, &kcfg->optionname);
447 if(*pnt == 'y' || *pnt == 'Y' ) kcfg->value = "1";
448 if(*pnt == 'n' || *pnt == 'N' ) kcfg->value = "0";
449 if(*pnt == 'm' || *pnt == 'M' ) kcfg->value = "2";
450 break;
451 case tok_menuname:
452 pnt = get_qstring(pnt, &kcfg->label);
453 break;
454 case tok_bool:
455 case tok_tristate:
456 pnt = get_qstring(pnt, &kcfg->label);
457 pnt = get_string(pnt, &kcfg->optionname);
458 break;
459 case tok_int:
460 case tok_hex:
461 pnt = get_qstring(pnt, &kcfg->label);
462 pnt = get_string(pnt, &kcfg->optionname);
463 pnt = get_string(pnt, &kcfg->value);
464 break;
465 case tok_dep_tristate:
466 pnt = get_qstring(pnt, &kcfg->label);
467 pnt = get_string(pnt, &kcfg->optionname);
468 pnt = skip_whitespace(pnt);
469 if( *pnt == '$') pnt++;
470 pnt = get_string(pnt, &kcfg->depend.str);
471
472
473
474
475
476
477
478
479
480
481
482
483
484 sprintf(fake_if,"[ \"$%s\" = \"y\" -o \"$%s\" = \"m\" ]; then",
485 kcfg->depend.str,kcfg->depend.str);
486 kcfg->cond = parse_if(fake_if);
487 if(kcfg->cond == NULL )
488 {
489 exit(1);
490 }
491 break;
492 case tok_comment:
493 pnt = get_qstring(pnt, &kcfg->label);
494 if( koption != NULL )
495 {
496 pnt = get_qstring(pnt, &kcfg->label);
497 koption->label = kcfg->label;
498 koption = NULL;
499 }
500 break;
501 case tok_menuoption:
502 if( strncmp(pnt, "next_comment", 12) == 0)
503 {
504 koption = kcfg;
505 }
506 else
507 {
508 pnt = get_qstring(pnt, &kcfg->label);
509 }
510 break;
511 case tok_else:
512 case tok_fi:
513 case tok_sound:
514 case tok_endmenu:
515 break;
516 case tok_if:
517
518
519
520
521 kcfg->cond = parse_if(pnt);
522 if(kcfg->cond == NULL )
523 {
524 exit(1);
525 }
526 break;
527 default:
528 exit(0);
529 }
530
531 return;
532 }
533
534
535
536
537 void dump_if(struct condition * cond)
538 {
539 printf(" ");
540 while(cond != NULL )
541 {
542 switch(cond->op){
543 case op_eq:
544 printf(" = ");
545 break;
546 case op_bang:
547 printf(" ! ");
548 break;
549 case op_neq:
550 printf(" != ");
551 break;
552 case op_and:
553 printf(" -a ");
554 break;
555 case op_lparen:
556 printf("(");
557 break;
558 case op_rparen:
559 printf(")");
560 break;
561 case op_variable:
562 printf("$%s", cond->variable.str);
563 break;
564 case op_constant:
565 printf("'%s'", cond->variable.str);
566 break;
567 default:
568 break;
569 }
570 cond = cond->next;
571 }
572
573 printf("\n");
574 }
575
576 static int do_source(char * filename)
577 {
578 char buffer[1024];
579 int offset;
580 int old_lineno;
581 char * old_file;
582 char * pnt;
583 FILE * infile;
584
585 if( strcmp(filename, "-") == 0 )
586 infile = stdin;
587 else
588 infile = fopen(filename,"r");
589
590
591
592
593
594 if(!infile) {
595 strcpy (buffer, "../");
596 strcat (buffer, filename);
597 infile = fopen(buffer,"r");
598 }
599
600 if(!infile) {
601 fprintf(stderr,"Unable to open file %s\n", filename);
602 return 1;
603 }
604 old_lineno = lineno;
605 lineno = 0;
606 if( infile != stdin ) {
607 old_file = current_file;
608 current_file = filename;
609 }
610 offset = 0;
611 while(1)
612 {
613 fgets(&buffer[offset], sizeof(buffer) - offset, infile);
614 if(feof(infile)) break;
615
616
617
618
619 pnt = buffer + strlen(buffer) - 1;
620 if( *pnt == '\n') *pnt-- = 0;
621 lineno++;
622 if( *pnt == '\\' )
623 {
624 offset = pnt - buffer;
625 }
626 else
627 {
628 parse(buffer);
629 offset = 0;
630 }
631 }
632 fclose(infile);
633 if( infile != stdin ) {
634 current_file = old_file;
635 }
636 lineno = old_lineno;
637 return 0;
638 }
639
640 int main(int argc, char * argv[])
641 {
642 #if 0
643 char buffer[1024];
644 char * pnt;
645 struct kconfig * cfg;
646 int i;
647 #endif
648
649
650
651
652 do_source("-");
653
654 if( menus_seen == 0 )
655 {
656 fprintf(stderr,"The config.in file for this platform does not support\n");
657 fprintf(stderr,"menus.\n");
658 exit(1);
659 }
660
661
662
663
664
665
666 fix_conditionals(config);
667
668
669
670
671 dump_tk_script(config);
672
673 #if 0
674
675
676
677
678 for(cfg = config; cfg; cfg = cfg->next)
679 {
680
681 if(cfg->cond != NULL && cfg->tok != tok_if)
682 dump_if(cfg->cond);
683
684 switch(cfg->tok)
685 {
686 case tok_menuname:
687 printf("main_menuname ");
688 break;
689 case tok_bool:
690 printf("bool ");
691 break;
692 case tok_tristate:
693 printf("tristate ");
694 break;
695 case tok_dep_tristate:
696 printf("dep_tristate ");
697 break;
698 case tok_int:
699 printf("int ");
700 break;
701 case tok_hex:
702 printf("hex ");
703 break;
704 case tok_comment:
705 printf("comment ");
706 break;
707 case tok_menuoption:
708 printf("menuoption ");
709 break;
710 case tok_else:
711 printf("else");
712 break;
713 case tok_fi:
714 printf("fi");
715 break;
716 case tok_if:
717 printf("if");
718 break;
719 default:
720 }
721
722 switch(cfg->tok)
723 {
724 case tok_menuoption:
725 case tok_comment:
726 case tok_menuname:
727 printf("%s\n", cfg->label);
728 break;
729 case tok_bool:
730 case tok_tristate:
731 case tok_dep_tristate:
732 case tok_int:
733 case tok_hex:
734 printf("%s %s\n", cfg->label, cfg->optionname);
735 break;
736 case tok_if:
737 dump_if(cfg->cond);
738 break;
739 case tok_nop:
740 case tok_endmenu:
741 break;
742 default:
743 printf("\n");
744 }
745 }
746 #endif
747
748 return 0;
749
750 }