~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/scripts/tkparse.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * tkparse.c
  3  *
  4  * Eric Youngdale was the original author of xconfig.
  5  * Michael Elizabeth Chastain (mec@shout.net) is the current maintainer.
  6  *
  7  * Parse a config.in file and translate it to a wish script.
  8  * This task has three parts:
  9  *
 10  *   tkparse.c  tokenize the input
 11  *   tkcond.c   transform 'if ...' statements
 12  *   tkgen.c    generate output
 13  *
 14  * Change History
 15  *
 16  * 7 January 1999, Michael Elizabeth Chastain, <mec@shout.net>
 17  * - Teach dep_tristate about a few literals, such as:
 18  *     dep_tristate 'foo' CONFIG_FOO m
 19  *   Also have it print an error message and exit on some parse failures.
 20  *
 21  * 14 January 1999, Michael Elizabeth Chastain, <mec@shout.net>
 22  * - Don't fclose stdin.  Thanks to Tony Hoyle for nailing this one.
 23  *
 24  * 14 January 1999, Michael Elizabeth Chastain, <mec@shout.net>
 25  * - Steam-clean this file.  I tested this by generating kconfig.tk for
 26  *   every architecture and comparing it character-for-character against
 27  *   the output of the old tkparse.
 28  *
 29  * 23 January 1999, Michael Elizabeth Chastain, <mec@shout.net>
 30  * - Remove bug-compatible code.
 31  *
 32  * 07 July 1999, Andrzej M. Krzysztofowicz, <ankry@mif.pg.gda.pl>
 33  * - Submenus implemented,
 34  * - plenty of option updating/displaying fixes,
 35  * - dep_bool, define_hex, define_int, define_string, define_tristate and
 36  *   undef implemented,
 37  * - dep_tristate fixed to support multiple dependencies,
 38  * - handling of variables with an empty value implemented,
 39  * - value checking for int and hex fields,
 40  * - more checking during condition parsing; choice variables are treated as
 41  *   all others now,
 42  *
 43  * TO DO:
 44  * - xconfig is at the end of its life cycle.  Contact <mec@shout.net> if
 45  *   you are interested in working on the replacement.
 46  */
 47 
 48 #include <stdio.h>
 49 #include <stdlib.h>
 50 #include <string.h>
 51 
 52 #include "tkparse.h"
 53 
 54 static struct kconfig * config_list = NULL;
 55 static struct kconfig * config_last = NULL;
 56 static const char * current_file = "<unknown file>";
 57 static int lineno = 0;
 58 
 59 static void do_source( const char * );
 60 
 61 #undef strcmp
 62 int my_strcmp( const char * s1, const char * s2 ) { return strcmp( s1, s2 ); }
 63 #define strcmp my_strcmp
 64 
 65 /*
 66  * Report a syntax error.
 67  */
 68 static void syntax_error( const char * msg )
 69 {
 70     fprintf( stderr, "%s: %d: %s\n", current_file, lineno, msg );
 71     exit( 1 );
 72 }
 73 
 74 
 75 
 76 /*
 77  * Find index of a specyfic variable in the symbol table.
 78  * Create a new entry if it does not exist yet.
 79  */
 80 #define VARTABLE_SIZE 2048
 81 struct variable vartable[VARTABLE_SIZE];
 82 int max_varnum = 0;
 83 
 84 int get_varnum( char * name )
 85 {
 86     int i;
 87     
 88     for ( i = 1; i <= max_varnum; i++ )
 89         if ( strcmp( vartable[i].name, name ) == 0 )
 90             return i;
 91     if (max_varnum > VARTABLE_SIZE-1)
 92         syntax_error( "Too many variables defined." );
 93     vartable[++max_varnum].name = malloc( strlen( name )+1 );
 94     strcpy( vartable[max_varnum].name, name );
 95     return max_varnum;
 96 }
 97 
 98 
 99 
100 /*
101  * Get a string.
102  */
103 static const char * get_string( const char * pnt, char ** label )
104 {
105     const char * word;
106 
107     word = pnt;
108     for ( ; ; )
109     {
110         if ( *pnt == '\0' || *pnt == ' ' || *pnt == '\t' )
111             break;
112         pnt++;
113     }
114 
115     *label = malloc( pnt - word + 1 );
116     memcpy( *label, word, pnt - word );
117     (*label)[pnt - word] = '\0';
118 
119     if ( *pnt != '\0' )
120         pnt++;
121     return pnt;
122 }
123 
124 
125 
126 /*
127  * Get a quoted string.
128  * Insert a '\' before any characters that need quoting.
129  */
130 static const char * get_qstring( const char * pnt, char ** label )
131 {
132     char quote_char;
133     char newlabel [2048];
134     char * pnt1;
135 
136     /* advance to the open quote */
137     for ( ; ; )
138     {
139         if ( *pnt == '\0' )
140             return pnt;
141         quote_char = *pnt++;
142         if ( quote_char == '"' || quote_char == '\'' )
143             break;
144     }
145 
146     /* copy into an intermediate buffer */
147     pnt1 = newlabel;
148     for ( ; ; )
149     {
150         if ( *pnt == '\0' )
151             syntax_error( "unterminated quoted string" );
152         if ( *pnt == quote_char && pnt[-1] != '\\' )
153             break;
154 
155         /* copy the character, quoting if needed */
156         if ( *pnt == '"' || *pnt == '\'' || *pnt == '[' || *pnt == ']' )
157             *pnt1++ = '\\';
158         *pnt1++ = *pnt++;
159     }
160 
161     /* copy the label into a permanent location */
162     *pnt1++ = '\0';
163     *label = (char *) malloc( pnt1 - newlabel );
164     memcpy( *label, newlabel, pnt1 - newlabel );
165 
166     /* skip over last quote and next whitespace */
167     pnt++;
168     while ( *pnt == ' ' || *pnt == '\t' )
169         pnt++;
170     return pnt;
171 }
172 
173 
174 
175 /*
176  * Get a quoted or unquoted string. It is recognized by the first 
177  * non-white character. '"' and '"' are not allowed inside the string.
178  */
179 static const char * get_qnqstring( const char * pnt, char ** label )
180 {
181     char quote_char;
182 
183     while ( *pnt == ' ' || *pnt == '\t' )
184         pnt++;
185 
186     if ( *pnt == '\0' )
187         return pnt;
188     quote_char = *pnt;
189     if ( quote_char == '"' || quote_char == '\'' )
190         return get_qstring( pnt, label );
191     else
192         return get_string( pnt, label );
193 }
194 
195 
196 
197 /*
198  * Tokenize an 'if' statement condition.
199  */
200 static struct condition * tokenize_if( const char * pnt )
201 {
202     struct condition * list;
203     struct condition * last;
204     struct condition * prev;
205 
206     /* eat the open bracket */
207     while ( *pnt == ' ' || *pnt == '\t' )
208         pnt++;
209     if ( *pnt != '[' )
210         syntax_error( "bad 'if' condition" );
211     pnt++;
212 
213     list = last = NULL;
214     for ( ; ; )
215     {
216         struct condition * cond;
217 
218         /* advance to the next token */
219         while ( *pnt == ' ' || *pnt == '\t' )
220             pnt++;
221         if ( *pnt == '\0' )
222             syntax_error( "unterminated 'if' condition" );
223         if ( *pnt == ']' )
224             return list;
225 
226         /* allocate a new token */
227         cond = malloc( sizeof(*cond) );
228         memset( cond, 0, sizeof(*cond) );
229         if ( last == NULL )
230             { list = last = cond; prev = NULL; }
231         else
232             { prev = last; last->next = cond; last = cond; }
233 
234         /* determine the token value */
235         if ( *pnt == '-' && pnt[1] == 'a' )
236         {
237             if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) )
238                 syntax_error( "incorrect argument" );
239             cond->op = op_and;  pnt += 2; continue;
240         }
241 
242         if ( *pnt == '-' && pnt[1] == 'o' )
243         {
244             if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) )
245                 syntax_error( "incorrect argument" );
246             cond->op = op_or;   pnt += 2; continue;
247         }
248 
249         if ( *pnt == '!' && pnt[1] == '=' )
250         {
251             if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) )
252                 syntax_error( "incorrect argument" );
253             cond->op = op_neq;  pnt += 2; continue;
254         }
255 
256         if ( *pnt == '=' )
257         {
258             if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) )
259                 syntax_error( "incorrect argument" );
260             cond->op = op_eq;   pnt += 1; continue;
261         }
262 
263         if ( *pnt == '!' )
264         {
265             if ( prev && ( prev->op != op_and && prev->op != op_or
266                       && prev->op != op_bang ) )
267                 syntax_error( "incorrect argument" );
268             cond->op = op_bang; pnt += 1; continue;
269         }
270 
271         if ( *pnt == '"' )
272         {
273             const char * word;
274 
275             if ( prev && ( prev->op == op_variable || prev->op == op_constant ) )
276                 syntax_error( "incorrect argument" );
277             /* advance to the word */
278             pnt++;
279             if ( *pnt == '$' )
280                 { cond->op = op_variable; pnt++; }
281             else
282                 { cond->op = op_constant; }
283 
284             /* find the end of the word */
285             word = pnt;
286             for ( ; ; )
287             {
288                 if ( *pnt == '\0' )
289                     syntax_error( "unterminated double quote" );
290                 if ( *pnt == '"' )
291                     break;
292                 pnt++;
293             }
294 
295             /* store a copy of this word */
296             {
297                 char * str = malloc( pnt - word + 1 );
298                 memcpy( str, word, pnt - word );
299                 str [pnt - word] = '\0';
300                 if ( cond->op == op_variable )
301                 {
302                     cond->nameindex = get_varnum( str );
303                     free( str );
304                 }
305                 else /* op_constant */
306                 {
307                     cond->str = str;
308                 }
309             }
310 
311             pnt++;
312             continue;
313         }
314 
315         /* unknown token */
316         syntax_error( "bad if condition" );
317     }
318 }
319 
320 
321 
322 /*
323  * Tokenize a choice list.  Choices appear as pairs of strings;
324  * note that I am parsing *inside* the double quotes.  Ugh.
325  */
326 static const char * tokenize_choices( struct kconfig * cfg_choose,
327     const char * pnt )
328 {
329     int default_checked = 0;
330     for ( ; ; )
331     {
332         struct kconfig * cfg;
333         char * buffer = malloc( 64 );
334 
335         /* skip whitespace */
336         while ( *pnt == ' ' || *pnt == '\t' )
337             pnt++;
338         if ( *pnt == '\0' )
339             return pnt;
340 
341         /* allocate a new kconfig line */
342         cfg = malloc( sizeof(*cfg) );
343         memset( cfg, 0, sizeof(*cfg) );
344         if ( config_last == NULL )
345             { config_last = config_list = cfg; }
346         else
347             { config_last->next = cfg; config_last = cfg; }
348 
349         /* fill out the line */
350         cfg->token      = token_choice_item;
351         cfg->cfg_parent = cfg_choose;
352         pnt = get_string( pnt, &cfg->label );
353         if ( ! default_checked &&
354              ! strncmp( cfg->label, cfg_choose->value, strlen( cfg_choose->value ) ) )
355         {
356             default_checked = 1;
357             free( cfg_choose->value );
358             cfg_choose->value = cfg->label;
359         }
360         while ( *pnt == ' ' || *pnt == '\t' )
361             pnt++;
362         pnt = get_string( pnt, &buffer );
363         cfg->nameindex = get_varnum( buffer );
364     }
365     if ( ! default_checked )
366         syntax_error( "bad 'choice' default value" );
367     return pnt;
368 }
369 
370 
371 
372 /*
373  * Tokenize one line.
374  */
375 static void tokenize_line( const char * pnt )
376 {
377     static struct kconfig * last_menuoption = NULL;
378     enum e_token token;
379     struct kconfig * cfg;
380     struct dependency ** dep_ptr;
381     char * buffer = malloc( 64 );
382 
383     /* skip white space */
384     while ( *pnt == ' ' || *pnt == '\t' )
385         pnt++;
386 
387     /*
388      * categorize the next token
389      */
390 
391 #define match_token(t, s) \
392     if (strncmp(pnt, s, strlen(s)) == 0) { token = t; pnt += strlen(s); break; }
393 
394     token = token_UNKNOWN;
395     switch ( *pnt )
396     {
397     default:
398         break;
399 
400     case '#':
401     case '\0':
402         return;
403 
404     case 'b':
405         match_token( token_bool, "bool" );
406         break;
407 
408     case 'c':
409         match_token( token_choice_header, "choice"  );
410         match_token( token_comment, "comment" );
411         break;
412 
413     case 'd':
414         match_token( token_define_bool, "define_bool" );
415         match_token( token_define_hex, "define_hex" );
416         match_token( token_define_int, "define_int" );
417         match_token( token_define_string, "define_string" );
418         match_token( token_define_tristate, "define_tristate" );
419         match_token( token_dep_bool, "dep_bool" );
420         match_token( token_dep_mbool, "dep_mbool" );
421         match_token( token_dep_tristate, "dep_tristate" );
422         break;
423 
424     case 'e':
425         match_token( token_else, "else" );
426         match_token( token_endmenu, "endmenu" );
427         break;
428 
429     case 'f':
430         match_token( token_fi, "fi" );
431         break;
432 
433     case 'h':
434         match_token( token_hex, "hex" );
435         break;
436 
437     case 'i':
438         match_token( token_if, "if" );
439         match_token( token_int, "int" );
440         break;
441 
442     case 'm':
443         match_token( token_mainmenu_name, "mainmenu_name" );
444         match_token( token_mainmenu_option, "mainmenu_option" );
445         break;
446 
447     case 's':
448         match_token( token_source, "source" );
449         match_token( token_string, "string" );
450         break;
451 
452     case 't':
453         match_token( token_then, "then" );
454         match_token( token_tristate, "tristate" );
455         break;
456 
457     case 'u':
458         match_token( token_unset, "unset" );
459         break;
460     }
461 
462 #undef match_token
463 
464     if ( token == token_source )
465     {
466         while ( *pnt == ' ' || *pnt == '\t' )
467             pnt++;
468         do_source( pnt );
469         return;
470     }
471 
472     if ( token == token_then )
473     {
474         if ( config_last != NULL && config_last->token == token_if )
475             return;
476         syntax_error( "bogus 'then'" );
477     }
478 
479 #if 0
480     if ( token == token_unset )
481     {
482         fprintf( stderr, "Ignoring 'unset' command\n" );
483         return;
484     }
485 #endif
486 
487     if ( token == token_UNKNOWN )
488         syntax_error( "unknown command" );
489 
490     /*
491      * Allocate an item.
492      */
493     cfg = malloc( sizeof(*cfg) );
494     memset( cfg, 0, sizeof(*cfg) );
495     if ( config_last == NULL )
496         { config_last = config_list = cfg; }
497     else
498         { config_last->next = cfg; config_last = cfg; }
499 
500     /*
501      * Tokenize the arguments.
502      */
503     while ( *pnt == ' ' || *pnt == '\t' )
504         pnt++;
505 
506     cfg->token = token;
507     switch ( token )
508     {
509     default:
510         syntax_error( "unknown token" );
511 
512     case token_bool:
513     case token_tristate:
514         pnt = get_qstring ( pnt, &cfg->label );
515         pnt = get_string  ( pnt, &buffer );
516         cfg->nameindex = get_varnum( buffer );
517         break;
518 
519     case token_choice_header:
520         {
521             static int choose_number = 0;
522             char * choice_list;
523 
524             pnt = get_qstring ( pnt, &cfg->label  );
525             pnt = get_qstring ( pnt, &choice_list );
526             pnt = get_string  ( pnt, &cfg->value  );
527             cfg->nameindex = -(choose_number++);
528             tokenize_choices( cfg, choice_list );
529             free( choice_list );
530         }
531         break;
532 
533     case token_comment:
534         pnt = get_qstring(pnt, &cfg->label);
535         if ( last_menuoption != NULL )
536         {
537             pnt = get_qstring(pnt, &cfg->label);
538             if (cfg->label == NULL)
539                 syntax_error( "missing comment text" );
540             last_menuoption->label = cfg->label;
541             last_menuoption = NULL;
542         }
543         break;
544 
545     case token_define_bool:
546     case token_define_tristate:
547         pnt = get_string( pnt, &buffer );
548         cfg->nameindex = get_varnum( buffer );
549         while ( *pnt == ' ' || *pnt == '\t' )
550             pnt++;
551         if ( ( pnt[0] == 'Y'  || pnt[0] == 'M' || pnt[0] == 'N'
552         ||     pnt[0] == 'y'  || pnt[0] == 'm' || pnt[0] == 'n' )
553         &&   ( pnt[1] == '\0' || pnt[1] == ' ' || pnt[1] == '\t' ) )
554         {
555             if      ( *pnt == 'n' || *pnt == 'N' ) cfg->value = strdup( "CONSTANT_N" );
556             else if ( *pnt == 'y' || *pnt == 'Y' ) cfg->value = strdup( "CONSTANT_Y" );
557             else if ( *pnt == 'm' || *pnt == 'M' ) cfg->value = strdup( "CONSTANT_M" );
558         }
559         else if ( *pnt == '$' )
560         {
561             pnt++;
562             pnt = get_string( pnt, &cfg->value );
563         }
564         else
565         {
566             syntax_error( "unknown define_bool value" );
567         }
568         get_varnum( cfg->value );
569         break;
570 
571     case token_define_hex:
572     case token_define_int:
573         pnt = get_string( pnt, &buffer );
574         cfg->nameindex = get_varnum( buffer );
575         pnt = get_string( pnt, &cfg->value );
576         break;
577 
578     case token_define_string:
579         pnt = get_string( pnt, &buffer );
580         cfg->nameindex = get_varnum( buffer );
581         pnt = get_qnqstring( pnt, &cfg->value );
582         if (cfg->value == NULL)
583             syntax_error( "missing value" );
584         break;
585 
586     case token_dep_bool:
587     case token_dep_mbool:
588     case token_dep_tristate:
589         pnt = get_qstring ( pnt, &cfg->label );
590         pnt = get_string  ( pnt, &buffer );
591         cfg->nameindex = get_varnum( buffer );
592 
593         while ( *pnt == ' ' || *pnt == '\t' )
594             pnt++;
595 
596         dep_ptr = &(cfg->depend);
597 
598         do {
599             *dep_ptr = (struct dependency *) malloc( sizeof( struct dependency ) );
600             (*dep_ptr)->next = NULL;
601 
602             if ( ( pnt[0] == 'Y'  || pnt[0] == 'M' || pnt[0] == 'N'
603             ||     pnt[0] == 'y'  || pnt[0] == 'm' || pnt[0] == 'n' )
604             &&   ( pnt[1] == '\0' || pnt[1] == ' ' || pnt[1] == '\t' ) )
605             {
606                 /* dep_tristate 'foo' CONFIG_FOO m */
607                 if      ( pnt[0] == 'Y' || pnt[0] == 'y' )
608                     (*dep_ptr)->name = strdup( "CONSTANT_Y" );
609                 else if ( pnt[0] == 'N' || pnt[0] == 'n' )
610                     (*dep_ptr)->name = strdup( "CONSTANT_N" );
611                 else
612                     (*dep_ptr)->name = strdup( "CONSTANT_M" );
613                 pnt++;
614                 get_varnum( (*dep_ptr)->name );
615             }
616             else if ( *pnt == '$' )
617             {
618                 pnt++;
619                 pnt = get_string( pnt, &(*dep_ptr)->name );
620                 get_varnum( (*dep_ptr)->name );
621             }
622             else
623             {
624                 syntax_error( "can't handle dep_bool/dep_mbool/dep_tristate condition" );
625             }
626             dep_ptr = &(*dep_ptr)->next;
627             while ( *pnt == ' ' || *pnt == '\t' )
628                 pnt++;
629         } while ( *pnt );
630 
631         /*
632          * Create a conditional for this object's dependencies.
633          */
634         {
635             char fake_if [1024];
636             struct dependency * dep;
637             struct condition ** cond_ptr;
638             int first = 1;
639 
640             cond_ptr = &(cfg->cond);
641             for ( dep = cfg->depend; dep; dep = dep->next )
642             {
643                 if ( token == token_dep_tristate
644                 && ! strcmp( dep->name, "CONSTANT_M" ) )
645                 {
646                     continue;
647                 }
648                 if ( first )
649                 {
650                     first = 0;
651                 }
652                 else
653                 {
654                     *cond_ptr = malloc( sizeof(struct condition) );
655                     memset( *cond_ptr, 0, sizeof(struct condition) );
656                     (*cond_ptr)->op = op_and;
657                     cond_ptr = &(*cond_ptr)->next;
658                 }
659                 *cond_ptr = malloc( sizeof(struct condition) );
660                 memset( *cond_ptr, 0, sizeof(struct condition) );
661                 (*cond_ptr)->op = op_lparen;
662                 if ( token == token_dep_bool )
663                     sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"\" ]; then",
664                         dep->name, dep->name );
665                 else
666                     sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"m\" -o \"$%s\" = \"\" ]; then",
667                         dep->name, dep->name, dep->name );
668                 (*cond_ptr)->next = tokenize_if( fake_if );
669                 while ( *cond_ptr )
670                     cond_ptr = &(*cond_ptr)->next;
671                 *cond_ptr = malloc( sizeof(struct condition) );
672                 memset( *cond_ptr, 0, sizeof(struct condition) );
673                 (*cond_ptr)->op = op_rparen;
674                 cond_ptr = &(*cond_ptr)->next;
675             }
676         }
677         break;
678 
679     case token_else:
680     case token_endmenu:
681     case token_fi:
682         break;
683 
684     case token_hex:
685     case token_int:
686         pnt = get_qstring ( pnt, &cfg->label );
687         pnt = get_string  ( pnt, &buffer );
688         cfg->nameindex = get_varnum( buffer );
689         pnt = get_string  ( pnt, &cfg->value );
690         break;
691 
692     case token_string:
693         pnt = get_qstring ( pnt, &cfg->label );
694         pnt = get_string  ( pnt, &buffer );
695         cfg->nameindex = get_varnum( buffer );
696         pnt = get_qnqstring  ( pnt, &cfg->value );
697         if (cfg->value == NULL)
698             syntax_error( "missing initial value" );
699         break;
700 
701     case token_if:
702         cfg->cond = tokenize_if( pnt );
703         break;
704 
705     case token_mainmenu_name:
706         pnt = get_qstring( pnt, &cfg->label );
707         break;
708 
709     case token_mainmenu_option:
710         if ( strncmp( pnt, "next_comment", 12 ) == 0 )
711             last_menuoption = cfg;
712         else
713             pnt = get_qstring( pnt, &cfg->label );
714         break;
715 
716     case token_unset:
717         pnt = get_string( pnt, &buffer );
718         cfg->nameindex = get_varnum( buffer );
719         while ( *pnt == ' ' || *pnt == '\t' )
720             pnt++;
721         while (*pnt)
722         {
723             cfg->next = (struct kconfig *) malloc( sizeof(struct kconfig) );
724             memset( cfg->next, 0, sizeof(struct kconfig) );
725             cfg = cfg->next;
726             cfg->token = token_unset;
727             pnt = get_string( pnt, &buffer );
728             cfg->nameindex = get_varnum( buffer );
729             while ( *pnt == ' ' || *pnt == '\t' )
730                 pnt++;
731         }
732         break;
733     }
734     return;
735 }
736 
737 
738 
739 /*
740  * Implement the "source" command.
741  */
742 static void do_source( const char * filename )
743 {
744     char buffer [2048];
745     FILE * infile;
746     const char * old_file;
747     int old_lineno;
748     int offset;
749 
750     /* open the file */
751     if ( strcmp( filename, "-" ) == 0 )
752         infile = stdin;
753     else
754         infile = fopen( filename, "r" );
755 
756     /* if that failed, try ../filename */
757     if ( infile == NULL )
758     {
759         sprintf( buffer, "../%s", filename );
760         infile = fopen( buffer, "r" );
761     }
762 
763     if ( infile == NULL )
764     {
765         sprintf( buffer, "unable to open %s", filename );
766         syntax_error( buffer );
767     }
768 
769     /* push the new file name and line number */
770     old_file     = current_file;
771     old_lineno   = lineno;
772     current_file = filename;
773     lineno       = 0;
774 
775     /* read and process lines */
776     for ( offset = 0; ; )
777     {
778         char * pnt;
779 
780         /* read a line */
781         fgets( buffer + offset, sizeof(buffer) - offset, infile );
782         if ( feof( infile ) )
783             break;
784         lineno++;
785 
786         /* strip the trailing return character */
787         pnt = buffer + strlen(buffer) - 1;
788         if ( *pnt == '\n' )
789             *pnt-- = '\0';
790 
791         /* eat \ NL pairs */
792         if ( *pnt == '\\' )
793         {
794             offset = pnt - buffer;
795             continue;
796         }
797 
798         /* tokenize this line */
799         tokenize_line( buffer );
800         offset = 0;
801     }
802 
803     /* that's all, folks */
804     if ( infile != stdin )
805         fclose( infile );
806     current_file = old_file;
807     lineno       = old_lineno;
808     return;
809 }
810 
811 
812 
813 /*
814  * Main program.
815  */
816 int main( int argc, const char * argv [] )
817 {
818     do_source        ( "-"         );
819     fix_conditionals ( config_list );
820     dump_tk_script   ( config_list );
821     return 0;
822 }
823 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.