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