OpenCores
URL https://opencores.org/ocsvn/mips_enhanced/mips_enhanced/trunk

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [bin/] [tkconfig/] [tkparse.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
/*
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
static char *genv;
739
static char *genv_extra;
740
 
741
/*
742
 * Implement the "source" command.
743
 */
744
static void do_source( const char * filename )
745
{
746
    char buffer[2048], buffer2[1024], buffer3[1024];
747
    FILE * infile, *hfile, *ofile;
748
    const char * old_file;
749
    int old_lineno;
750
    int offset;
751
    static first = 0, first2 = 0, first3 = 0;
752
 
753
    strcpy(buffer, filename);
754
 
755
    /* open the file */
756
    if ( strcmp( filename, "-" ) == 0 )
757
        infile = stdin;
758
    else
759
        infile = fopen( filename, "r" );
760
 
761
    /* if that failed, try second argument as path */
762
    if (( infile == NULL ) && (genv))
763
    {
764
        sprintf( buffer, "%s/%s", genv, filename );
765
        infile = fopen( buffer, "r" );
766
    }
767
 
768
    /* if that failed, try third argument as path */
769
    if (( infile == NULL ) && (genv_extra))
770
    {
771
        sprintf( buffer, "%s/%s", genv_extra, filename );
772
        infile = fopen( buffer, "r" );
773
    }
774
 
775
    if ( infile == NULL )
776
    {
777
        sprintf( buffer, "unable to open %s", buffer );
778
        syntax_error( buffer );
779
    } else {
780
        strcpy(buffer2, buffer);
781
        strcpy(buffer3, buffer);
782
        strcat(buffer, ".h");
783
        hfile = fopen( buffer, "r" );
784
        if (hfile != NULL) {
785
          if (first)
786
            ofile = fopen( "tkconfig.h", "a" );
787
          else {
788
            ofile = fopen( "tkconfig.h", "w" );
789
            first = 1;
790
          }
791
          while (!feof(hfile)) {
792
            offset = fread(buffer, 1, 1024, hfile);
793
            fwrite(buffer, 1, offset, ofile);
794
          }
795
          fclose( hfile );
796
          fclose( ofile );
797
        }
798
        strcat(buffer2, ".help");
799
        hfile = fopen( buffer2, "r" );
800
        if (hfile != NULL) {
801
          if (first2)
802
            ofile = fopen( "config.help", "a" );
803
          else {
804
            ofile = fopen( "config.help", "w" );
805
            first2 = 1;
806
          }
807
          while (!feof(hfile)) {
808
            offset = fread(buffer, 1, 1024, hfile);
809
            fwrite(buffer, 1, offset, ofile);
810
          }
811
          fclose( hfile );
812
          fclose( ofile );
813
        }
814
        strcat(buffer3, ".vhd");
815
        hfile = fopen( buffer3, "r" );
816
        if (hfile != NULL) {
817
          if (first3)
818
            ofile = fopen( "config.vhd.h", "a" );
819
          else {
820
            ofile = fopen( "config.vhd.h", "w" );
821
            first3 = 1;
822
          }
823
          while (!feof(hfile)) {
824
            offset = fread(buffer, 1, 1024, hfile);
825
            fwrite(buffer, 1, offset, ofile);
826
          }
827
          fclose( hfile );
828
          fclose( ofile );
829
        }
830
    }
831
 
832
    /* push the new file name and line number */
833
    old_file     = current_file;
834
    old_lineno   = lineno;
835
    current_file = filename;
836
    lineno       = 0;
837
 
838
    /* read and process lines */
839
    for ( offset = 0; ; )
840
    {
841
        char * pnt;
842
 
843
        /* read a line */
844
        fgets( buffer + offset, sizeof(buffer) - offset, infile );
845
        if ( feof( infile ) )
846
            break;
847
        lineno++;
848
 
849
        /* strip the trailing return character */
850
        pnt = buffer + strlen(buffer) - 1;
851
        if ( *pnt == '\n' )
852
            *pnt-- = '\0';
853
 
854
        /* eat \ NL pairs */
855
        if ( *pnt == '\\' )
856
        {
857
            offset = pnt - buffer;
858
            continue;
859
        }
860
 
861
        /* tokenize this line */
862
        tokenize_line( buffer );
863
        offset = 0;
864
    }
865
 
866
    /* that's all, folks */
867
    if ( infile != stdin )
868
        fclose( infile );
869
    current_file = old_file;
870
    lineno       = old_lineno;
871
    return;
872
}
873
 
874
 
875
 
876
/*
877
 * Main program.
878
 */
879
int main( int argc, char * argv [] )
880
{
881
    if (argc >= 3) genv = argv[2];
882
    if (argc == 4) genv_extra = argv[3];
883
    do_source        ( argv[1]         );
884
    fix_conditionals ( config_list );
885
    dump_tk_script   ( config_list );
886
    return 0;
887
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.