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.str = 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.str = 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.str = 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 ", 6) == 0)
330 {
331 tok = tok_make;
332 }
333 else if (strncmp(pnt, "comment", 7) == 0)
334 {
335 tok = tok_comment;
336 pnt += 7;
337 }
338 else if (strncmp(pnt, "choice", 6) == 0)
339 {
340 tok = tok_choose;
341 pnt += 6;
342 }
343 else if (strncmp(pnt, "define_bool", 11) == 0)
344 {
345 tok = tok_define;
346 pnt += 11;
347 }
348 else if (strncmp(pnt, "bool", 4) == 0)
349 {
350 tok = tok_bool;
351 pnt += 4;
352 }
353 else if (strncmp(pnt, "tristate", 8) == 0)
354 {
355 tok = tok_tristate;
356 pnt += 8;
357 }
358 else if (strncmp(pnt, "dep_tristate", 12) == 0)
359 {
360 tok = tok_dep_tristate;
361 pnt += 12;
362 }
363 else if (strncmp(pnt, "int", 3) == 0)
364 {
365 tok = tok_int;
366 pnt += 3;
367 }
368 else if (strncmp(pnt, "hex", 3) == 0)
369 {
370 tok = tok_hex;
371 pnt += 3;
372 }
373 else if (strncmp(pnt, "if", 2) == 0)
374 {
375 tok = tok_if;
376 pnt += 2;
377 }
378 else if (strncmp(pnt, "else", 4) == 0)
379 {
380 tok = tok_else;
381 pnt += 4;
382 }
383 else if (strncmp(pnt, "fi", 2) == 0)
384 {
385 tok = tok_fi;
386 pnt += 2;
387 }
388 else if (strncmp(pnt, "endmenu", 7) == 0)
389 {
390 tok = tok_endmenu;
391 pnt += 7;
392 }
393
394 if( tok == tok_unknown)
395 {
396 if( clast != NULL && clast->tok == tok_if
397 && strcmp(pnt,"then") == 0) return;
398 if( current_file != NULL )
399 fprintf(stderr, "unknown command=%s(%s %d)\n", pnt,
400 current_file, lineno);
401 else
402 fprintf(stderr, "unknown command=%s(%d)\n", pnt,lineno);
403 return;
404 }
405
406
407
408
409
410 kcfg = (struct kconfig *) malloc(sizeof(struct kconfig));
411 memset(kcfg, 0, sizeof(struct kconfig));
412 kcfg->tok = tok;
413 if( clast != NULL )
414 {
415 clast->next = kcfg;
416 clast = kcfg;
417 }
418 else
419 {
420 clast = config = kcfg;
421 }
422
423 pnt = skip_whitespace(pnt);
424
425
426
427
428
429 switch (tok)
430 {
431 case tok_choose:
432 pnt = get_qstring(pnt, &kcfg->label);
433 pnt = get_qstring(pnt, &kcfg->optionname);
434 pnt = get_string(pnt, &kcfg->value);
435
436
437
438
439 parse_choices(kcfg, kcfg->optionname);
440 free(kcfg->optionname);
441 sprintf(tmpbuf, "tmpvar_%d", choose_number++);
442 kcfg->optionname = strdup(tmpbuf);
443 break;
444 case tok_define:
445 pnt = get_string(pnt, &kcfg->optionname);
446 if(*pnt == 'y' || *pnt == 'Y' ) kcfg->value = "1";
447 if(*pnt == 'n' || *pnt == 'N' ) kcfg->value = "0";
448 if(*pnt == 'm' || *pnt == 'M' ) kcfg->value = "2";
449 break;
450 case tok_menuname:
451 pnt = get_qstring(pnt, &kcfg->label);
452 break;
453 case tok_bool:
454 case tok_tristate:
455 pnt = get_qstring(pnt, &kcfg->label);
456 pnt = get_string(pnt, &kcfg->optionname);
457 break;
458 case tok_int:
459 case tok_hex:
460 pnt = get_qstring(pnt, &kcfg->label);
461 pnt = get_string(pnt, &kcfg->optionname);
462 pnt = get_string(pnt, &kcfg->value);
463 break;
464 case tok_dep_tristate:
465 pnt = get_qstring(pnt, &kcfg->label);
466 pnt = get_string(pnt, &kcfg->optionname);
467 pnt = skip_whitespace(pnt);
468 if( *pnt == '$') pnt++;
469 pnt = get_string(pnt, &kcfg->depend.str);
470
471
472
473
474
475
476
477
478
479
480
481
482
483 sprintf(fake_if,"[ \"$%s\" = \"y\" -o \"$%s\" = \"m\" ]; then",
484 kcfg->depend.str,kcfg->depend.str);
485 kcfg->cond = parse_if(fake_if);
486 if(kcfg->cond == NULL )
487 {
488 exit(1);
489 }
490 break;
491 case tok_comment:
492 pnt = get_qstring(pnt, &kcfg->label);
493 if( koption != NULL )
494 {
495 pnt = get_qstring(pnt, &kcfg->label);
496 koption->label = kcfg->label;
497 koption = NULL;
498 }
499 break;
500 case tok_menuoption:
501 if( strncmp(pnt, "next_comment", 12) == 0)
502 {
503 koption = kcfg;
504 }
505 else
506 {
507 pnt = get_qstring(pnt, &kcfg->label);
508 }
509 break;
510 case tok_make:
511 kcfg->value=strdup(pnt);
512 break;
513 case tok_else:
514 case tok_fi:
515 case tok_endmenu:
516 break;
517 case tok_if:
518
519
520
521
522 kcfg->cond = parse_if(pnt);
523 if(kcfg->cond == NULL )
524 {
525 exit(1);
526 }
527 break;
528 default:
529 exit(0);
530 }
531
532 return;
533 }
534
535
536
537
538 void dump_if(struct condition * cond)
539 {
540 printf(" ");
541 while(cond != NULL )
542 {
543 switch(cond->op){
544 case op_eq:
545 printf(" = ");
546 break;
547 case op_bang:
548 printf(" ! ");
549 break;
550 case op_neq:
551 printf(" != ");
552 break;
553 case op_and:
554 printf(" -a ");
555 break;
556 case op_lparen:
557 printf("(");
558 break;
559 case op_rparen:
560 printf(")");
561 break;
562 case op_variable:
563 printf("$%s", cond->variable.str);
564 break;
565 case op_constant:
566 printf("'%s'", cond->variable.str);
567 break;
568 default:
569 break;
570 }
571 cond = cond->next;
572 }
573
574 printf("\n");
575 }
576
577 static int do_source(char * filename)
578 {
579 char buffer[1024];
580 int offset;
581 int old_lineno;
582 char * old_file;
583 char * pnt;
584 FILE * infile;
585
586 if( strcmp(filename, "-") == 0 )
587 infile = stdin;
588 else
589 infile = fopen(filename,"r");
590
591
592
593
594
595 if(!infile) {
596 strcpy (buffer, "../");
597 strcat (buffer, filename);
598 infile = fopen(buffer,"r");
599 }
600
601 if(!infile) {
602 fprintf(stderr,"Unable to open file %s\n", filename);
603 return 1;
604 }
605 old_lineno = lineno;
606 lineno = 0;
607 if( infile != stdin ) {
608 old_file = current_file;
609 current_file = filename;
610 }
611 offset = 0;
612 while(1)
613 {
614 fgets(&buffer[offset], sizeof(buffer) - offset, infile);
615 if(feof(infile)) break;
616
617
618
619
620 pnt = buffer + strlen(buffer) - 1;
621 if( *pnt == '\n') *pnt-- = 0;
622 lineno++;
623 if( *pnt == '\\' )
624 {
625 offset = pnt - buffer;
626 }
627 else
628 {
629 parse(buffer);
630 offset = 0;
631 }
632 }
633 fclose(infile);
634 if( infile != stdin ) {
635 current_file = old_file;
636 }
637 lineno = old_lineno;
638 return 0;
639 }
640
641 int main(int argc, char * argv[])
642 {
643 #if 0
644 char buffer[1024];
645 char * pnt;
646 struct kconfig * cfg;
647 int i;
648 #endif
649
650
651
652
653 do_source("-");
654
655 if( menus_seen == 0 )
656 {
657 fprintf(stderr,"The config.in file for this platform does not support\n");
658 fprintf(stderr,"menus.\n");
659 exit(1);
660 }
661
662
663
664
665
666
667 fix_conditionals(config);
668
669
670
671
672 dump_tk_script(config);
673
674 #if 0
675
676
677
678
679 for(cfg = config; cfg; cfg = cfg->next)
680 {
681
682 if(cfg->cond != NULL && cfg->tok != tok_if)
683 dump_if(cfg->cond);
684
685 switch(cfg->tok)
686 {
687 case tok_menuname:
688 printf("main_menuname ");
689 break;
690 case tok_bool:
691 printf("bool ");
692 break;
693 case tok_tristate:
694 printf("tristate ");
695 break;
696 case tok_dep_tristate:
697 printf("dep_tristate ");
698 break;
699 case tok_int:
700 printf("int ");
701 break;
702 case tok_hex:
703 printf("hex ");
704 break;
705 case tok_comment:
706 printf("comment ");
707 break;
708 case tok_menuoption:
709 printf("menuoption ");
710 break;
711 case tok_else:
712 printf("else");
713 break;
714 case tok_fi:
715 printf("fi");
716 break;
717 case tok_if:
718 printf("if");
719 break;
720 default:
721 }
722
723 switch(cfg->tok)
724 {
725 case tok_menuoption:
726 case tok_comment:
727 case tok_menuname:
728 printf("%s\n", cfg->label);
729 break;
730 case tok_bool:
731 case tok_tristate:
732 case tok_dep_tristate:
733 case tok_int:
734 case tok_hex:
735 printf("%s %s\n", cfg->label, cfg->optionname);
736 break;
737 case tok_if:
738 dump_if(cfg->cond);
739 break;
740 case tok_nop:
741 case tok_endmenu:
742 break;
743 default:
744 printf("\n");
745 }
746 }
747 #endif
748
749 return 0;
750
751 }