Ignore:
Timestamp:
Apr 16, 2001, 7:11:03 PM (24 years ago)
Author:
sandervl
Message:

updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/wrc/preproc.c

    r3476 r5522  
    99#include <stdlib.h>
    1010#include <string.h>
     11#include <assert.h>
    1112
    1213#include "wrc.h"
    1314#include "utils.h"
    1415#include "preproc.h"
    15 #include "parser.h"
    1616
    1717
    1818extern void set_pp_ignore(int); /* From parser.l */
    1919
    20 static char *current_define;
    21 
    2220#define HASHKEY         2039
    23 static struct pp_entry *pp_defines[HASHKEY];
     21static pp_entry_t *pp_defines[HASHKEY];
    2422
    2523#define MAXIFSTACK      64
    26 static struct if_state ifstack[MAXIFSTACK];
    27 static int ifstackidx = 0;
     24static if_state_t if_stack[MAXIFSTACK];
     25static int if_stack_idx = 0;
    2826
    2927#if 0
     28void pp_status(void) __attribute__((destructor));
    3029void pp_status(void)
    3130{
     
    3332        int sum;
    3433        int total = 0;
    35         struct pp_entry *ppp;
    36 
    37         printf("Defines statistics:\n");
     34        pp_entry_t *ppp;
     35
     36        fprintf(stderr, "Defines statistics:\n");
    3837        for(i = 0; i < HASHKEY; i++)
    3938        {
     
    4241                        sum++;
    4342                total += sum;
    44                 printf("%4d, %3d\n", i, sum);
    45         }
    46         printf("Total defines: %d\n", total);
    47 }
    48 #pragma exit pp_status
     43                fprintf(stderr, "%4d, %3d\n", i, sum);
     44        }
     45        fprintf(stderr, "Total defines: %d\n", total);
     46}
    4947#endif
    5048
    5149/* Don't comment on the hash, its primitive but functional... */
    52 int pp_hash(char *str)
     50int pphash(char *str)
    5351{
    5452        int sum = 0;
     
    5856}
    5957
    60 struct pp_entry *pp_lookup(char *ident)
    61 {
    62         int index = pp_hash(ident);
    63         struct pp_entry *ppp;
    64         for(ppp = pp_defines[index]; ppp; ppp = ppp->next)
     58pp_entry_t *pplookup(char *ident)
     59{
     60        int idx = pphash(ident);
     61        pp_entry_t *ppp;
     62
     63        for(ppp = pp_defines[idx]; ppp; ppp = ppp->next)
    6564        {
    6665                if(!strcmp(ident, ppp->ident))
     
    7069}
    7170
    72 void set_define(char *name)
    73 {
    74         current_define = xstrdup(name);
    75 }
    76 
    7771void del_define(char *name)
    7872{
    79         int index;
    80         struct pp_entry *ppp;
    81 
    82         if((ppp = pp_lookup(name)) == NULL)
     73        int idx;
     74        pp_entry_t *ppp;
     75
     76        if((ppp = pplookup(name)) == NULL)
    8377        {
    8478                if(pedantic)
     
    8781        }
    8882
    89         index = pp_hash(name);
    90         if(pp_defines[index] == ppp)
    91         {
    92                 pp_defines[index] = ppp->next;
    93                 if(pp_defines[index])
    94                         pp_defines[index]->prev = NULL;
     83        if(ppp->iep)
     84        {
     85                if(debuglevel & DEBUGLEVEL_PPMSG)
     86                        fprintf(stderr, "del_define: %s:%d: includelogic removed, include_ppp='%s', file=%s\n", input_name, line_number, name, ppp->iep->filename);
     87                if(ppp->iep == includelogiclist)
     88                {
     89                        includelogiclist = ppp->iep->next;
     90                        if(includelogiclist)
     91                                includelogiclist->prev = NULL;
     92                }
     93                else
     94                {
     95                        ppp->iep->prev->next = ppp->iep->next;
     96                        if(ppp->iep->next)
     97                                ppp->iep->next->prev = ppp->iep->prev;
     98                }
     99                free(ppp->iep->filename);
     100                free(ppp->iep);
     101        }
     102
     103        idx = pphash(name);
     104        if(pp_defines[idx] == ppp)
     105        {
     106                pp_defines[idx] = ppp->next;
     107                if(pp_defines[idx])
     108                        pp_defines[idx]->prev = NULL;
    95109        }
    96110        else
     
    100114                        ppp->next->prev = ppp->prev;
    101115        }
     116
    102117        free(ppp);
    103 }
    104 
    105 void add_define(char *text)
     118
     119        if(debuglevel & DEBUGLEVEL_PPMSG)
     120                printf("Deleted (%s, %d) <%s>\n", input_name, line_number, name);
     121}
     122
     123pp_entry_t *add_define(char *def, char *text)
    106124{
    107125        int len;
    108126        char *cptr;
    109         int index = pp_hash(current_define);
    110         struct pp_entry *ppp;
    111         if(pp_lookup(current_define) != NULL)
     127        int idx = pphash(def);
     128        pp_entry_t *ppp;
     129
     130        if((ppp = pplookup(def)) != NULL)
    112131        {
    113132                if(pedantic)
    114                         yywarning("Redefinition of %s", current_define);
    115                 del_define(current_define);
    116         }
    117         ppp = (struct pp_entry *)xmalloc(sizeof(struct pp_entry));
    118         ppp->ident = current_define;
    119         ppp->subst = xstrdup(text);
    120         ppp->next = pp_defines[index];
    121         pp_defines[index] = ppp;
     133                        yywarning("Redefinition of %s\n\tPrevious definition: %s:%d", def, ppp->filename, ppp->linenumber);
     134                del_define(def);
     135        }
     136        ppp = (pp_entry_t *)xmalloc(sizeof(pp_entry_t));
     137        ppp->ident = def;
     138        ppp->type = def_define;
     139        ppp->subst.text = text;
     140        ppp->filename = input_name ? xstrdup(input_name) : "<internal or cmdline>";
     141        ppp->linenumber = input_name ? line_number : 0;
     142        ppp->next = pp_defines[idx];
     143        pp_defines[idx] = ppp;
    122144        if(ppp->next)
    123145                ppp->next->prev = ppp;
    124         /* Strip trailing white space from subst text */
    125         len = strlen(ppp->subst);
    126         while(len && strchr(" \t\r\n", ppp->subst[len-1]))
    127         {
    128                 ppp->subst[--len] = '\0';
    129         }
    130         /* Strip leading white space from subst text */
    131         for(cptr = ppp->subst; *cptr && strchr(" \t\r", *cptr); cptr++)
     146        if(text)
     147        {
     148                /* Strip trailing white space from subst text */
     149                len = strlen(text);
     150                while(len && strchr(" \t\r\n", text[len-1]))
     151                {
     152                        text[--len] = '\0';
     153                }
     154                /* Strip leading white space from subst text */
     155                for(cptr = text; *cptr && strchr(" \t\r", *cptr); cptr++)
    132156                ;
    133         if(ppp->subst != cptr)
    134                 memmove(ppp->subst, cptr, strlen(cptr)+1);
    135         if(yydebug)
    136                 printf("Added (%s, %d) <%s> to <%s>\n", input_name, line_number, ppp->ident, ppp->subst);
    137 }
    138 
    139 void add_cmdline_define(char *set)
     157                if(text != cptr)
     158                        memmove(text, cptr, strlen(cptr)+1);
     159        }
     160        if(debuglevel & DEBUGLEVEL_PPMSG)
     161                printf("Added define (%s, %d) <%s> to <%s>\n", input_name, line_number, ppp->ident, text ? text : "(null)");
     162
     163        return ppp;
     164}
     165
     166pp_entry_t *add_cmdline_define(char *set)
    140167{
    141168        char *cpy = xstrdup(set);       /* Because gcc passes a R/O string */
     
    143170        if(cptr)
    144171                *cptr = '\0';
    145         set_define(cpy);
    146         add_define(cptr ? cptr+1 : "");
    147         free(cpy);
    148 }
    149 
    150 /*kso added test for __SEMICOLON__ since __WIN32OS2__ isn't defined! */
    151 #if defined(__SEMICOLON__) || defined(_Windows) || defined(__MSDOS__) || defined(__WIN32OS2__)
     172        return add_define(cpy, xstrdup(cptr ? cptr+1 : ""));
     173}
     174
     175pp_entry_t *add_special_define(char *id)
     176{
     177        pp_entry_t *ppp = add_define(xstrdup(id), xstrdup(""));
     178        ppp->type = def_special;
     179        return ppp;
     180}
     181
     182pp_entry_t *add_macro(char *id, marg_t *args[], int nargs, mtext_t *exp)
     183{
     184        int idx = pphash(id);
     185        pp_entry_t *ppp;
     186
     187        if((ppp = pplookup(id)) != NULL)
     188        {
     189                if(pedantic)
     190                        yywarning("Redefinition of %s\n\tPrevious definition: %s:%d", id, ppp->filename, ppp->linenumber);
     191                del_define(id);
     192        }
     193        ppp = (pp_entry_t *)xmalloc(sizeof(pp_entry_t));
     194        ppp->ident      = id;
     195        ppp->type       = def_macro;
     196        ppp->margs      = args;
     197        ppp->nargs      = nargs;
     198        ppp->subst.mtext= exp;
     199        ppp->filename = input_name ? xstrdup(input_name) : "<internal or cmdline>";
     200        ppp->linenumber = input_name ? line_number : 0;
     201        ppp->next       = pp_defines[idx];
     202        pp_defines[idx] = ppp;
     203        if(ppp->next)
     204                ppp->next->prev = ppp;
     205
     206        if(debuglevel & DEBUGLEVEL_PPMSG)
     207        {
     208                fprintf(stderr, "Added macro (%s, %d) <%s(%d)> to <", input_name, line_number, ppp->ident, nargs);
     209                for(; exp; exp = exp->next)
     210                {
     211                        switch(exp->type)
     212                        {
     213                        case exp_text:
     214                                fprintf(stderr, " \"%s\" ", exp->subst.text);
     215                                break;
     216                        case exp_stringize:
     217                                fprintf(stderr, " #(%d) ", exp->subst.argidx);
     218                                break;
     219                        case exp_concat:
     220                                fprintf(stderr, "##");
     221                                break;
     222                        case exp_subst:
     223                                fprintf(stderr, " <%d> ", exp->subst.argidx);
     224                                break;
     225                        }
     226                }
     227                fprintf(stderr, ">\n");
     228        }
     229        return ppp;
     230}
     231
     232
     233/*
     234 *-------------------------------------------------------------------------
     235 * Include management
     236 *-------------------------------------------------------------------------
     237 */
     238#if defined(_Windows) || defined(__MSDOS__)
    152239#define INCLUDESEPARATOR        ";"
    153 #warning "Using ; as include separator"
    154240#else
    155 #warning "Using : as include separator"
    156241#define INCLUDESEPARATOR        ":"
    157242#endif
     
    192277}
    193278
    194 FILE *open_include(const char *name, int search)
     279FILE *open_include(const char *name, int search, char **newpath)
    195280{
    196281        char *cpy = xstrdup(name);
     
    212297        {
    213298                /* Search current dir and then -I path */
    214                 fp = fopen(name, "rt");
     299                fp = fopen(cpy, "rb");
    215300                if(fp)
    216301                {
    217                         if(yydebug)
     302                        if(debuglevel & DEBUGLEVEL_PPMSG)
    218303                                printf("Going to include <%s>\n", name);
    219                         free(cpy);
     304                        if(newpath)
     305                                *newpath = cpy;
     306                        else
     307                                free(cpy);
    220308                        return fp;
    221309                }
     
    229317                strcat(path, "/");
    230318                strcat(path, cpy);
    231                 fp = fopen(path, "rt");
    232                 if(fp && yydebug)
     319                fp = fopen(path, "rb");
     320                if(fp && (debuglevel & DEBUGLEVEL_PPMSG))
    233321                        printf("Going to include <%s>\n", path);
    234                 free(path);
    235322                if(fp)
    236323                {
     324                        if(newpath)
     325                                *newpath = path;
     326                        else
     327                                free(path);
    237328                        free(cpy);
    238329                        return fp;
    239330                }
    240 
     331                free(path);
    241332        }
    242333        free(cpy);
     334        if(newpath)
     335                *newpath = NULL;
    243336        return NULL;
    244337}
    245338
    246 void push_if(int truecase, int wastrue, int nevertrue)
    247 {
    248         if(ifstackidx >= MAXIFSTACK-1)
    249                 internal_error(__FILE__, __LINE__, "#if stack overflow");
    250         ifstack[ifstackidx].current = truecase && !wastrue;
    251         ifstack[ifstackidx].hasbeentrue = wastrue;
    252         ifstack[ifstackidx].nevertrue = nevertrue;
    253         if(nevertrue || !(truecase && !wastrue))
    254                 set_pp_ignore(1);
    255         if(yydebug)
    256                 printf("push_if: %d %d %d (%d %d %d)\n",
    257                         truecase,
    258                         wastrue,
    259                         nevertrue,
    260                         ifstack[ifstackidx].current,
    261                         ifstack[ifstackidx].hasbeentrue,
    262                         ifstack[ifstackidx].nevertrue);
    263         ifstackidx++;
    264 }
    265 
    266 int pop_if(void)
    267 {
    268         if(ifstackidx <= 0)
    269                 yyerror("#endif without #if|#ifdef|#ifndef (#if stack underflow)");
    270         ifstackidx--;
    271         if(yydebug)
    272                 printf("pop_if: %d %d %d\n",
    273                         ifstack[ifstackidx].current,
    274                         ifstack[ifstackidx].hasbeentrue,
    275                         ifstack[ifstackidx].nevertrue);
    276         if(ifstack[ifstackidx].nevertrue || !ifstack[ifstackidx].current)
    277                 set_pp_ignore(0);
    278         return ifstack[ifstackidx].hasbeentrue || ifstack[ifstackidx].current;
    279 }
    280 
    281 int isnevertrue_if(void)
    282 {
    283         return ifstackidx > 0 && ifstack[ifstackidx-1].nevertrue;
    284 }
    285 
     339/*
     340 *-------------------------------------------------------------------------
     341 * #if, #ifdef, #ifndef, #else, #elif and #endif state management
     342 *
     343 * #if state transitions are made on basis of the current TOS and the next
     344 * required state. The state transitions are required to housekeep because
     345 * #if:s can be nested. The ignore case is activated to prevent output from
     346 * within a false clause.
     347 * Some special cases come from the fact that the #elif cases are not
     348 * binary, but three-state. The problem is that all other elif-cases must
     349 * be false when one true one has been found. A second problem is that the
     350 * #else clause is a final clause. No extra #else:s may follow.
     351 *
     352 * The states mean:
     353 * if_true      Process input to output
     354 * if_false     Process input but no output
     355 * if_ignore    Process input but no output
     356 * if_elif      Process input but no output
     357 * if_elsefalse Process input but no output
     358 * if_elsettrue Process input to output
     359 *
     360 * The possible state-sequences are [state(stack depth)] (rest can be deduced):
     361 *      TOS             #if 1           #else                   #endif
     362 *      if_true(n)      if_true(n+1)    if_elsefalse(n+1)
     363 *      if_false(n)     if_ignore(n+1)  if_ignore(n+1)
     364 *      if_elsetrue(n)  if_true(n+1)    if_elsefalse(n+1)
     365 *      if_elsefalse(n) if_ignore(n+1)  if_ignore(n+1)
     366 *      if_elif(n)      if_ignore(n+1)  if_ignore(n+1)
     367 *      if_ignore(n)    if_ignore(n+1)  if_ignore(n+1)
     368 *
     369 *      TOS             #if 1           #elif 0         #else           #endif
     370 *      if_true(n)      if_true(n+1)    if_elif(n+1)    if_elif(n+1)
     371 *      if_false(n)     if_ignore(n+1)  if_ignore(n+1)  if_ignore(n+1)
     372 *      if_elsetrue(n)  if_true(n+1)    if_elif(n+1)    if_elif(n+1)
     373 *      if_elsefalse(n) if_ignore(n+1)  if_ignore(n+1)  if_ignore(n+1)
     374 *      if_elif(n)      if_ignore(n+1)  if_ignore(n+1)  if_ignore(n+1)
     375 *      if_ignore(n)    if_ignore(n+1)  if_ignore(n+1)  if_ignore(n+1)
     376 *
     377 *      TOS             #if 0           #elif 1         #else           #endif
     378 *      if_true(n)      if_false(n+1)   if_true(n+1)    if_elsefalse(n+1)
     379 *      if_false(n)     if_ignore(n+1)  if_ignore(n+1)  if_ignore(n+1)
     380 *      if_elsetrue(n)  if_false(n+1)   if_true(n+1)    if_elsefalse(n+1)
     381 *      if_elsefalse(n) if_ignore(n+1)  if_ignore(n+1)  if_ignore(n+1)
     382 *      if_elif(n)      if_ignore(n+1)  if_ignore(n+1)  if_ignore(n+1)
     383 *      if_ignore(n)    if_ignore(n+1)  if_ignore(n+1)  if_ignore(n+1)
     384 *
     385 *-------------------------------------------------------------------------
     386 */
     387static char *if_state_str[] = {
     388        "if_false",
     389        "if_true",
     390        "if_elif",
     391        "if_elsefalse",
     392        "if_elsetrue",
     393        "if_ignore"
     394};
     395
     396void push_if(if_state_t s)
     397{
     398        if(if_stack_idx >= MAXIFSTACK)
     399                internal_error(__FILE__, __LINE__, "#if-stack overflow; #{if,ifdef,ifndef} nested too deeply (> %d)", MAXIFSTACK);
     400
     401        if(debuglevel & DEBUGLEVEL_PPLEX)
     402                fprintf(stderr, "Push if %s:%d: %s(%d) -> %s(%d)\n", input_name, line_number, if_state_str[if_state()], if_stack_idx, if_state_str[s], if_stack_idx+1);
     403
     404        if_stack[if_stack_idx++] = s;
     405
     406        switch(s)
     407        {
     408        case if_true:
     409        case if_elsetrue:
     410                break;
     411        case if_false:
     412        case if_elsefalse:
     413        case if_elif:
     414        case if_ignore:
     415                push_ignore_state();
     416                break;
     417        }
     418}
     419
     420if_state_t pop_if(void)
     421{
     422        if(if_stack_idx <= 0)
     423                yyerror("#{endif,else,elif} without #{if,ifdef,ifndef} (#if-stack underflow)");
     424
     425        switch(if_state())
     426        {
     427        case if_true:
     428        case if_elsetrue:
     429                break;
     430        case if_false:
     431        case if_elsefalse:
     432        case if_elif:
     433        case if_ignore:
     434                pop_ignore_state();
     435                break;
     436        }
     437
     438        if(debuglevel & DEBUGLEVEL_PPLEX)
     439                fprintf(stderr, "Pop if %s:%d: %s(%d) -> %s(%d)\n",
     440                                input_name,
     441                                line_number,
     442                                if_state_str[if_state()],
     443                                if_stack_idx,
     444                                if_state_str[if_stack[if_stack_idx <= 1 ? if_true : if_stack_idx-2]],
     445                                if_stack_idx-1);
     446
     447        return if_stack[--if_stack_idx];
     448}
     449
     450if_state_t if_state(void)
     451{
     452        if(!if_stack_idx)
     453                return if_true;
     454        else
     455                return if_stack[if_stack_idx-1];
     456}
     457
     458
     459void next_if_state(int i)
     460{
     461        switch(if_state())
     462        {
     463        case if_true:
     464        case if_elsetrue:
     465                push_if(i ? if_true : if_false);
     466                break;
     467        case if_false:
     468        case if_elsefalse:
     469        case if_elif:
     470        case if_ignore:
     471                push_if(if_ignore);
     472                break;
     473        default:
     474                internal_error(__FILE__, __LINE__, "Invalid if_state (%d) in #{if,ifdef,ifndef} directive", (int)if_state());
     475        }
     476}
     477
     478int get_if_depth(void)
     479{
     480        return if_stack_idx;
     481}
     482
Note: See TracChangeset for help on using the changeset viewer.