LCOV - code coverage report
Current view: top level - soltools/mkdepend - parse.c (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 0 240 0.0 %
Date: 2015-06-13 12:38:46 Functions: 0 12 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* $XConsortium: parse.c,v 1.30 94/04/17 20:10:38 gildea Exp $ */
       3             : /*
       4             : 
       5             : Copyright (c) 1993, 1994  X Consortium
       6             : 
       7             : Permission is hereby granted, free of charge, to any person obtaining a copy
       8             : of this software and associated documentation files (the "Software"), to deal
       9             : in the Software without restriction, including without limitation the rights
      10             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      11             : copies of the Software, and to permit persons to whom the Software is
      12             : furnished to do so, subject to the following conditions:
      13             : 
      14             : The above copyright notice and this permission notice shall be included in
      15             : all copies or substantial portions of the Software.
      16             : 
      17             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      18             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      19             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
      20             : X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
      21             : AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
      22             : CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      23             : 
      24             : Except as contained in this notice, the name of the X Consortium shall not be
      25             : used in advertising or otherwise to promote the sale, use or other dealings
      26             : in this Software without prior written authorization from the X Consortium.
      27             : 
      28             : */
      29             : 
      30             : #include "def.h"
      31             : char *hash_lookup( char *symbol, struct symhash *symbols );
      32             : void hash_undefine( char *symbol, struct symhash *symbols );
      33             : int gobble( struct filepointer *filep, struct inclist *file,
      34             :     struct inclist *file_red, struct symhash *symbols );
      35             : int deftype ( char *line, struct filepointer *filep,
      36             :     struct inclist *file_red, struct inclist *file,
      37             :     int parse_it, struct symhash *symbols);
      38             : int zero_value(char *exp, struct filepointer *filep,
      39             :     struct inclist *file_red, struct symhash *symbols);
      40             : 
      41             : extern char *directives[];
      42             : extern struct symhash *maininclist;
      43             : 
      44           0 : int find_includes(struct filepointer *filep, struct inclist *file, struct inclist *file_red, int recursion, boolean failOK, struct IncludesCollection* incCollection, struct symhash *symbols)
      45             : {
      46             :     char   *line;
      47             :     int    type;
      48             :     boolean recfailOK;
      49             : 
      50           0 :     while ((line = get_line(filep))) {
      51           0 :         switch(type = deftype(line, filep, file_red, file, TRUE, symbols)) {
      52             :         case IF:
      53             :         doif:
      54           0 :             type = find_includes(filep, file,
      55             :                 file_red, recursion+1, failOK, incCollection, symbols);
      56           0 :             while ((type == ELIF) || (type == ELIFFALSE) ||
      57             :                    (type == ELIFGUESSFALSE))
      58           0 :                 type = gobble(filep, file, file_red, symbols);
      59           0 :             if (type == ELSE)
      60           0 :                 gobble(filep, file, file_red, symbols);
      61           0 :             break;
      62             :         case IFFALSE:
      63             :         case IFGUESSFALSE:
      64             :             doiffalse:
      65           0 :             if (type == IFGUESSFALSE || type == ELIFGUESSFALSE)
      66           0 :                 recfailOK = TRUE;
      67             :             else
      68           0 :                 recfailOK = failOK;
      69           0 :             type = gobble(filep, file, file_red, symbols);
      70           0 :             if (type == ELSE)
      71           0 :                 find_includes(filep, file,
      72             :                       file_red, recursion+1, recfailOK, incCollection, symbols);
      73           0 :             else if (type == ELIF)
      74           0 :                 goto doif;
      75           0 :             else if ((type == ELIFFALSE) || (type == ELIFGUESSFALSE))
      76             :                 goto doiffalse;
      77           0 :             break;
      78             :         case IFDEF:
      79             :         case IFNDEF:
      80           0 :             if ((type == IFDEF && hash_lookup(line, symbols))
      81           0 :              || (type == IFNDEF && !hash_lookup(line, symbols))) {
      82             :                 debug(1,(type == IFNDEF ?
      83             :                     "line %d: %s !def'd in %s via %s%s\n" : "",
      84             :                     filep->f_line, line,
      85             :                     file->i_file, file_red->i_file, ": doit"));
      86           0 :                 type = find_includes(filep, file,
      87             :                     file_red, recursion+1, failOK, incCollection, symbols);
      88           0 :                 while (type == ELIF || type == ELIFFALSE || type == ELIFGUESSFALSE)
      89           0 :                     type = gobble(filep, file, file_red, symbols);
      90           0 :                 if (type == ELSE)
      91           0 :                     gobble(filep, file, file_red, symbols);
      92             :             }
      93             :             else {
      94             :                 debug(1,(type == IFDEF ?
      95             :                     "line %d: %s !def'd in %s via %s%s\n" : "",
      96             :                     filep->f_line, line,
      97             :                     file->i_file, file_red->i_file, ": gobble"));
      98           0 :                 type = gobble(filep, file, file_red, symbols);
      99           0 :                 if (type == ELSE)
     100           0 :                     find_includes(filep, file,
     101             :                         file_red, recursion + 1, failOK, incCollection, symbols);
     102           0 :                 else if (type == ELIF)
     103           0 :                         goto doif;
     104           0 :                 else if (type == ELIFFALSE || type == ELIFGUESSFALSE)
     105             :                         goto doiffalse;
     106             :             }
     107           0 :             break;
     108             :         case ELSE:
     109             :         case ELIFFALSE:
     110             :         case ELIFGUESSFALSE:
     111             :         case ELIF:
     112           0 :             if (!recursion)
     113           0 :                 gobble(filep, file, file_red, symbols);
     114             :             /*fall-through*/
     115             :         case ENDIF:
     116           0 :             if (recursion)
     117           0 :                 return type;
     118             :             /*fall-through*/
     119             :         case DEFINE:
     120           0 :             define(line, &symbols);
     121           0 :             break;
     122             :         case UNDEF:
     123           0 :             if (!*line) {
     124           0 :                 warning("%s, line %d: incomplete undef == \"%s\"\n",
     125             :                 file_red->i_file, filep->f_line, line);
     126           0 :                 break;
     127             :             }
     128           0 :             hash_undefine(line, symbols);
     129           0 :             break;
     130             :         case INCLUDE:
     131           0 :             add_include(filep, file, file_red, line, FALSE, failOK, incCollection, symbols);
     132           0 :             break;
     133             :         case INCLUDEDOT:
     134           0 :             add_include(filep, file, file_red, line, TRUE, failOK, incCollection, symbols);
     135           0 :             break;
     136             :         case ERROR:
     137           0 :                 warning("%s: %d: %s\n", file_red->i_file,
     138             :                  filep->f_line, line);
     139           0 :                 break;
     140             : 
     141             :         case PRAGMA:
     142             :         case IDENT:
     143             :         case SCCS:
     144             :         case EJECT:
     145           0 :             break;
     146             :         case -1:
     147           0 :             warning("%s", file_red->i_file);
     148           0 :             if (file_red != file)
     149           0 :                 warning1(" (reading %s)", file->i_file);
     150           0 :             warning1(", line %d: unknown directive == \"%s\"\n",
     151             :                  filep->f_line, line);
     152           0 :             break;
     153             :         case -2:
     154           0 :             warning("%s", file_red->i_file);
     155           0 :             if (file_red != file)
     156           0 :                 warning1(" (reading %s)", file->i_file);
     157           0 :             warning1(", line %d: incomplete include == \"%s\"\n",
     158             :                  filep->f_line, line);
     159           0 :             break;
     160             :         }
     161             :     }
     162           0 :     return -1;
     163             : }
     164             : 
     165           0 : int gobble(struct filepointer *filep,
     166             :            struct inclist *file,
     167             :            struct inclist *file_red,
     168             :            struct symhash *symbols)
     169             : {
     170             :     char   *line;
     171             :     int    type;
     172             : 
     173           0 :     while ((line = get_line(filep))) {
     174           0 :         switch(type = deftype(line, filep, file_red, file, FALSE, symbols)) {
     175             :         case IF:
     176             :         case IFFALSE:
     177             :         case IFGUESSFALSE:
     178             :         case IFDEF:
     179             :         case IFNDEF:
     180           0 :             type = gobble(filep, file, file_red, symbols);
     181           0 :             while ((type == ELIF) || (type == ELIFFALSE) ||
     182             :                    (type == ELIFGUESSFALSE))
     183           0 :                 type = gobble(filep, file, file_red, symbols);
     184           0 :             if (type == ELSE)
     185           0 :                     (void)gobble(filep, file, file_red, symbols);
     186           0 :             break;
     187             :         case ELSE:
     188             :         case ENDIF:
     189             :             debug(0,("%s, line %d: #%s\n",
     190             :                 file->i_file, filep->f_line,
     191             :                 directives[type]));
     192           0 :             return type;
     193             :         case DEFINE:
     194             :         case UNDEF:
     195             :         case INCLUDE:
     196             :         case INCLUDEDOT:
     197             :         case PRAGMA:
     198             :         case ERROR:
     199             :         case IDENT:
     200             :         case SCCS:
     201             :         case EJECT:
     202           0 :             break;
     203             :         case ELIF:
     204             :         case ELIFFALSE:
     205             :         case ELIFGUESSFALSE:
     206           0 :             return type;
     207             :         case -1:
     208           0 :             warning("%s, line %d: unknown directive == \"%s\"\n",
     209             :                 file_red->i_file, filep->f_line, line);
     210           0 :             break;
     211             :         }
     212             :     }
     213           0 :     return -1;
     214             : }
     215             : 
     216             : /*
     217             :  * Decide what type of # directive this line is.
     218             :  */
     219           0 : int deftype (char *line, struct filepointer *filep, struct inclist *file_red, struct inclist *file, int parse_it, struct symhash *symbols)
     220             : {
     221             :     char   *p;
     222             :     char    *directive, savechar;
     223             :     int    ret;
     224             : 
     225             :     /*
     226             :      * Parse the directive...
     227             :      */
     228           0 :     directive=line+1;
     229           0 :     while (*directive == ' ' || *directive == '\t')
     230           0 :         directive++;
     231             : 
     232           0 :     p = directive;
     233           0 :     while (*p >= 'a' && *p <= 'z')
     234           0 :         p++;
     235           0 :     savechar = *p;
     236           0 :     *p = '\0';
     237           0 :     ret = match(directive, directives);
     238           0 :     *p = savechar;
     239             : 
     240             :     /* If we don't recognize this compiler directive or we happen to just
     241             :      * be gobbling up text while waiting for an #endif or #elif or #else
     242             :      * in the case of an #elif we must check the zero_value and return an
     243             :      * ELIF or an ELIFFALSE.
     244             :      */
     245             : 
     246           0 :     if (ret == ELIF && !parse_it)
     247             :     {
     248           0 :         while (*p == ' ' || *p == '\t')
     249           0 :             p++;
     250             :         /*
     251             :          * parse an expression.
     252             :          */
     253             :         debug(0,("%s, line %d: #elif %s ",
     254             :            file->i_file, filep->f_line, p));
     255           0 :         ret = zero_value(p, filep, file_red, symbols);
     256           0 :         if (ret != IF)
     257             :         {
     258             :           debug(0,("false...\n"));
     259           0 :           if (ret == IFFALSE)
     260           0 :               return ELIFFALSE;
     261             :           else
     262           0 :               return ELIFGUESSFALSE;
     263             :           }
     264             :         else
     265             :         {
     266             :           debug(0,("true...\n"));
     267           0 :           return ELIF;
     268             :         }
     269             :     }
     270             : 
     271           0 :     if (ret < 0 || ! parse_it)
     272           0 :         return ret;
     273             : 
     274             :     /*
     275             :      * now decide how to parse the directive, and do it.
     276             :      */
     277           0 :     while (*p == ' ' || *p == '\t')
     278           0 :         p++;
     279           0 :     switch (ret) {
     280             :     case IF:
     281             :         /*
     282             :          * parse an expression.
     283             :          */
     284           0 :         ret = zero_value(p, filep, file_red, symbols);
     285             :         debug(0,("%s, line %d: %s #if %s\n",
     286             :              file->i_file, filep->f_line, ret?"false":"true", p));
     287           0 :         break;
     288             :     case IFDEF:
     289             :     case IFNDEF:
     290             :         debug(0,("%s, line %d: #%s %s\n",
     291             :             file->i_file, filep->f_line, directives[ret], p));
     292             :         //fall-through
     293             :     case UNDEF:
     294             :         /*
     295             :          * separate the name of a single symbol.
     296             :          */
     297           0 :         while (isalnum(*p) || *p == '_')
     298           0 :             *line++ = *p++;
     299           0 :         *line = '\0';
     300           0 :         break;
     301             :     case INCLUDE:
     302             :         debug(2,("%s, line %d: #include %s\n",
     303             :             file->i_file, filep->f_line, p));
     304             : 
     305             :         /* Support ANSI macro substitution */
     306             :         {
     307           0 :             char *sym = hash_lookup(p, symbols);
     308           0 :             while (sym)
     309             :             {
     310           0 :                 p = sym;
     311             :                 debug(3,("%s : #includes SYMBOL %s\n",
     312             :                             file->i_incstring,
     313             :                             sym));
     314             :                 /* mark file as having included a 'soft include' */
     315           0 :                 file->i_included_sym = TRUE;
     316           0 :                 sym = hash_lookup(p, symbols);
     317             :             }
     318             :         }
     319             : 
     320             :         /*
     321             :          * Separate the name of the include file.
     322             :          */
     323           0 :         while (*p && *p != '"' && *p != '<')
     324           0 :             p++;
     325           0 :         if (! *p)
     326           0 :             return -2;
     327           0 :         if (*p++ == '"') {
     328           0 :             ret = INCLUDEDOT;
     329           0 :             while (*p && *p != '"')
     330           0 :                 *line++ = *p++;
     331             :         } else
     332           0 :             while (*p && *p != '>')
     333           0 :                 *line++ = *p++;
     334           0 :         *line = '\0';
     335           0 :         break;
     336             :     case DEFINE:
     337             :         /*
     338             :          * copy the definition back to the beginning of the line.
     339             :          */
     340           0 :         memmove (line, p, strlen(p));
     341           0 :         break;
     342             :     case ELSE:
     343             :     case ENDIF:
     344             :     case ELIF:
     345             :     case PRAGMA:
     346             :     case ERROR:
     347             :     case IDENT:
     348             :     case SCCS:
     349             :     case EJECT:
     350             :         debug(0,("%s, line %d: #%s\n",
     351             :             file->i_file, filep->f_line, directives[ret]));
     352             :         /*
     353             :          * nothing to do.
     354             :          */
     355           0 :         break;
     356             :     }
     357           0 :     return ret;
     358             : }
     359             : 
     360             : /*
     361             :  * HACK! - so that we do not have to introduce 'symbols' in each cppsetup.c
     362             :  * function...  It's safe, functions from cppsetup.c don't return here.
     363             :  */
     364             : struct symhash *global_symbols = NULL;
     365             : 
     366           0 : char * isdefined( char *symbol )
     367             : {
     368           0 :     return hash_lookup( symbol, global_symbols );
     369             : }
     370             : 
     371             : /*
     372             :  * Return type based on if the #if expression evaluates to 0
     373             :  */
     374           0 : int zero_value(char *exp, struct filepointer *filep, struct inclist *file_red, struct symhash *symbols)
     375             : {
     376           0 :     global_symbols = symbols; /* HACK! see above */
     377           0 :     if (cppsetup(exp, filep, file_red))
     378           0 :         return IFFALSE;
     379             :     else
     380           0 :         return IF;
     381             : }
     382             : 
     383           0 : void define( char *def, struct symhash **symbols )
     384             : {
     385             :     char *val;
     386             : 
     387             :     /* Separate symbol name and its value */
     388           0 :     val = def;
     389           0 :     while (isalnum(*val) || *val == '_')
     390           0 :         val++;
     391           0 :     if (*val)
     392           0 :         *val++ = '\0';
     393           0 :     while (*val == ' ' || *val == '\t')
     394           0 :         val++;
     395             : 
     396           0 :     if (!*val)
     397           0 :         val = "1";
     398           0 :     hash_define( def, val, symbols );
     399           0 : }
     400             : 
     401           0 : static int hash( char *str )
     402             : {
     403             :     /* Hash (Kernighan and Ritchie) */
     404           0 :     unsigned int hashval = 0;
     405             : 
     406           0 :     for ( ; *str; str++ )
     407             :     {
     408           0 :         hashval = ( hashval * SYMHASHSEED ) + ( *str );
     409             :     }
     410             : 
     411           0 :     return hashval & ( SYMHASHMEMBERS - 1 );
     412             : }
     413             : 
     414           0 : struct symhash *hash_copy( struct symhash *symbols )
     415             : {
     416             :     int i;
     417             :     struct symhash *newsym;
     418           0 :     if ( !symbols )
     419           0 :         return NULL;
     420             : 
     421           0 :     newsym = (struct symhash *) malloc( sizeof( struct symhash ) );
     422             : 
     423           0 :     for ( i = 0; i < SYMHASHMEMBERS; ++i )
     424             :     {
     425           0 :         if ( !symbols->s_pairs[ i ] )
     426           0 :             newsym->s_pairs[ i ] = NULL;
     427             :         else
     428             :         {
     429           0 :             struct pair *it = symbols->s_pairs[ i ];
     430           0 :             struct pair *nw = newsym->s_pairs[ i ] = (struct pair*) malloc( sizeof( struct pair ) );
     431           0 :             nw->p_name = it->p_name;
     432           0 :             nw->p_value = it->p_value;
     433           0 :             nw->p_next = NULL;
     434             : 
     435           0 :             while ( it->p_next )
     436             :             {
     437           0 :                 nw->p_next = (struct pair*) malloc( sizeof( struct pair ) );
     438           0 :                 it = it->p_next;
     439           0 :                 nw = nw->p_next;
     440           0 :                 nw->p_name = it->p_name;
     441           0 :                 nw->p_value = it->p_value;
     442           0 :                 nw->p_next = NULL;
     443             :             }
     444             :         }
     445             :     }
     446           0 :     return newsym;
     447             : }
     448             : 
     449           0 : void hash_free( struct symhash *symbols )
     450             : {
     451             :     int i;
     452             : 
     453           0 :     if ( !symbols )
     454           0 :         return;
     455             : 
     456           0 :     for ( i = 0; i < SYMHASHMEMBERS; ++i )
     457             :     {
     458           0 :         struct pair *it = symbols->s_pairs[ i ];
     459             :         struct pair *next;
     460           0 :         while ( it )
     461             :         {
     462           0 :             next = it->p_next;
     463           0 :             free( it );
     464           0 :             it = next;
     465             :         }
     466             :     }
     467           0 :     free( symbols->s_pairs );
     468             : }
     469             : 
     470           0 : void hash_define( char *name, char *val, struct symhash **symbols )
     471             : {
     472             :     int hashval;
     473             :     struct pair *it;
     474             : 
     475           0 :     if ( !symbols )
     476           0 :         return;
     477             : 
     478             :     /* Make space if it's needed */
     479           0 :     if ( *symbols == NULL )
     480             :     {
     481             :         int i;
     482             : 
     483           0 :         *symbols = (struct symhash *) malloc( sizeof( struct symhash ) );
     484           0 :         if ( *symbols == NULL )
     485           0 :             fatalerr( "malloc()/realloc() failure in insert_defn()\n" );
     486             : 
     487           0 :         for ( i = 0; i < SYMHASHMEMBERS; ++i )
     488           0 :             (*symbols)->s_pairs[i] = NULL;
     489             :     }
     490             : 
     491           0 :     hashval = hash( name );
     492           0 :     it = (*symbols)->s_pairs[ hashval ];
     493             : 
     494             :     /* Replace/insert the symbol */
     495           0 :     if ( it == NULL )
     496             :     {
     497           0 :         it = (*symbols)->s_pairs[ hashval ] = (struct pair*) malloc( sizeof( struct pair ) );
     498           0 :         it->p_name = copy( name );
     499           0 :         it->p_value = copy( val );
     500           0 :         it->p_next = NULL;
     501             :     }
     502           0 :     else if ( strcmp( it->p_name, name ) == 0 )
     503             :     {
     504           0 :         it->p_value = copy( val );
     505             :     }
     506             :     else
     507             :     {
     508           0 :         while ( it->p_next && ( strcmp( it->p_next->p_name, name ) != 0 ) )
     509             :         {
     510           0 :             it = it->p_next;
     511             :         }
     512           0 :         if ( it->p_next )
     513           0 :             it->p_next->p_name = copy( name );
     514             :         else
     515             :         {
     516           0 :             it->p_next = (struct pair*) malloc( sizeof( struct pair ) );
     517           0 :             it->p_next->p_name = copy( name );
     518           0 :             it->p_next->p_value = copy( val );
     519           0 :             it->p_next->p_next = NULL;
     520             :         }
     521             :     }
     522             : }
     523             : 
     524           0 : char *hash_lookup( char *symbol, struct symhash *symbols )
     525             : {
     526             :     struct pair *it;
     527             : 
     528           0 :     if ( !symbols )
     529           0 :         return NULL;
     530             : 
     531           0 :     it = symbols->s_pairs[ hash( symbol ) ];
     532             : 
     533           0 :     while ( it && ( strcmp( it->p_name, symbol ) != 0 ) )
     534             :     {
     535           0 :         it = it->p_next;
     536             :     }
     537           0 :     if ( it )
     538           0 :         return it->p_value;
     539             : 
     540           0 :     return NULL;
     541             : }
     542             : 
     543           0 : void hash_undefine( char *symbol, struct symhash *symbols )
     544             : {
     545             :     int hashval;
     546             :     struct pair *it;
     547             : 
     548           0 :     if ( !symbols )
     549           0 :         return;
     550             : 
     551           0 :     hashval = hash( symbol );
     552           0 :     it = symbols->s_pairs[ hashval ];
     553             : 
     554             :     /* Replace/insert the symbol */
     555           0 :     if ( it == NULL )
     556           0 :         return;
     557           0 :     else if ( strcmp( it->p_name, symbol ) == 0 )
     558             :     {
     559           0 :         if ( it->p_next )
     560             :         {
     561             :             struct pair *tmp;
     562           0 :             it->p_name = it->p_next->p_name;
     563           0 :             it->p_value = it->p_next->p_value;
     564           0 :             tmp = it->p_next->p_next;
     565           0 :             free( it->p_next );
     566           0 :             it->p_next = tmp;
     567             :         }
     568             :         else
     569             :         {
     570           0 :             free( it );
     571           0 :             symbols->s_pairs[ hashval ] = NULL;
     572             :         }
     573             :     }
     574             :     else
     575             :     {
     576           0 :         while ( it->p_next && ( strcmp( it->p_next->p_name, symbol ) != 0 ) )
     577             :         {
     578           0 :             it = it->p_next;
     579             :         }
     580           0 :         if ( it->p_next )
     581             :         {
     582           0 :             struct pair *tmp = it->p_next;
     583           0 :             it->p_next = it->p_next->p_next;
     584           0 :             free( tmp );
     585             :         }
     586             :     }
     587             : }
     588             : 
     589             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11