LCOV - code coverage report
Current view: top level - soltools/mkdepend - parse.c (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 240 0.0 %
Date: 2014-04-14 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( register struct filepointer *filep, struct inclist *file,
      34             :     struct inclist *file_red, struct symhash *symbols );
      35             : int deftype ( register char *line, register struct filepointer *filep,
      36             :     register struct inclist *file_red, register struct inclist *file,
      37             :     int parse_it, struct symhash *symbols);
      38             : int zero_value(register char *exp, register struct filepointer *filep,
      39             :     register struct inclist *file_red, register 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             :     register char   *line;
      47             :     register 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             :         case ENDIF:
     115           0 :             if (recursion)
     116           0 :                 return(type);
     117             :         case DEFINE:
     118           0 :             define(line, &symbols);
     119           0 :             break;
     120             :         case UNDEF:
     121           0 :             if (!*line) {
     122           0 :                 warning("%s, line %d: incomplete undef == \"%s\"\n",
     123             :                 file_red->i_file, filep->f_line, line);
     124           0 :                 break;
     125             :             }
     126           0 :             hash_undefine(line, symbols);
     127           0 :             break;
     128             :         case INCLUDE:
     129           0 :             add_include(filep, file, file_red, line, FALSE, failOK, incCollection, symbols);
     130           0 :             break;
     131             :         case INCLUDEDOT:
     132           0 :             add_include(filep, file, file_red, line, TRUE, failOK, incCollection, symbols);
     133           0 :             break;
     134             :         case ERROR:
     135           0 :                 warning("%s: %d: %s\n", file_red->i_file,
     136             :                  filep->f_line, line);
     137           0 :                 break;
     138             : 
     139             :         case PRAGMA:
     140             :         case IDENT:
     141             :         case SCCS:
     142             :         case EJECT:
     143           0 :             break;
     144             :         case -1:
     145           0 :             warning("%s", file_red->i_file);
     146           0 :             if (file_red != file)
     147           0 :                 warning1(" (reading %s)", file->i_file);
     148           0 :             warning1(", line %d: unknown directive == \"%s\"\n",
     149             :                  filep->f_line, line);
     150           0 :             break;
     151             :         case -2:
     152           0 :             warning("%s", file_red->i_file);
     153           0 :             if (file_red != file)
     154           0 :                 warning1(" (reading %s)", file->i_file);
     155           0 :             warning1(", line %d: incomplete include == \"%s\"\n",
     156             :                  filep->f_line, line);
     157           0 :             break;
     158             :         }
     159             :     }
     160           0 :     return(-1);
     161             : }
     162             : 
     163           0 : int gobble(filep, file, file_red, symbols)
     164             :     register struct filepointer *filep;
     165             :     struct inclist      *file, *file_red;
     166             :     struct symhash      *symbols;
     167             : {
     168             :     register char   *line;
     169             :     register int    type;
     170             : 
     171           0 :     while ((line = get_line(filep))) {
     172           0 :         switch(type = deftype(line, filep, file_red, file, FALSE, symbols)) {
     173             :         case IF:
     174             :         case IFFALSE:
     175             :         case IFGUESSFALSE:
     176             :         case IFDEF:
     177             :         case IFNDEF:
     178           0 :             type = gobble(filep, file, file_red, symbols);
     179           0 :             while ((type == ELIF) || (type == ELIFFALSE) ||
     180             :                    (type == ELIFGUESSFALSE))
     181           0 :                 type = gobble(filep, file, file_red, symbols);
     182           0 :             if (type == ELSE)
     183           0 :                     (void)gobble(filep, file, file_red, symbols);
     184           0 :             break;
     185             :         case ELSE:
     186             :         case ENDIF:
     187             :             debug(0,("%s, line %d: #%s\n",
     188             :                 file->i_file, filep->f_line,
     189             :                 directives[type]));
     190           0 :             return(type);
     191             :         case DEFINE:
     192             :         case UNDEF:
     193             :         case INCLUDE:
     194             :         case INCLUDEDOT:
     195             :         case PRAGMA:
     196             :         case ERROR:
     197             :         case IDENT:
     198             :         case SCCS:
     199             :         case EJECT:
     200           0 :             break;
     201             :         case ELIF:
     202             :         case ELIFFALSE:
     203             :         case ELIFGUESSFALSE:
     204           0 :             return(type);
     205             :         case -1:
     206           0 :             warning("%s, line %d: unknown directive == \"%s\"\n",
     207             :                 file_red->i_file, filep->f_line, line);
     208           0 :             break;
     209             :         }
     210             :     }
     211           0 :     return(-1);
     212             : }
     213             : 
     214             : /*
     215             :  * Decide what type of # directive this line is.
     216             :  */
     217           0 : int deftype (line, filep, file_red, file, parse_it, symbols)
     218             :     register char   *line;
     219             :     register struct filepointer *filep;
     220             :     register struct inclist *file_red, *file;
     221             :     int parse_it;
     222             :     struct symhash  *symbols;
     223             : {
     224             :     register char   *p;
     225             :     char    *directive, savechar;
     226             :     register int    ret;
     227             : 
     228             :     /*
     229             :      * Parse the directive...
     230             :      */
     231           0 :     directive=line+1;
     232           0 :     while (*directive == ' ' || *directive == '\t')
     233           0 :         directive++;
     234             : 
     235           0 :     p = directive;
     236           0 :     while (*p >= 'a' && *p <= 'z')
     237           0 :         p++;
     238           0 :     savechar = *p;
     239           0 :     *p = '\0';
     240           0 :     ret = match(directive, directives);
     241           0 :     *p = savechar;
     242             : 
     243             :     /* If we don't recognize this compiler directive or we happen to just
     244             :      * be gobbling up text while waiting for an #endif or #elif or #else
     245             :      * in the case of an #elif we must check the zero_value and return an
     246             :      * ELIF or an ELIFFALSE.
     247             :      */
     248             : 
     249           0 :     if (ret == ELIF && !parse_it)
     250             :     {
     251           0 :         while (*p == ' ' || *p == '\t')
     252           0 :         p++;
     253             :         /*
     254             :          * parse an expression.
     255             :          */
     256             :         debug(0,("%s, line %d: #elif %s ",
     257             :            file->i_file, filep->f_line, p));
     258           0 :         ret = zero_value(p, filep, file_red, symbols);
     259           0 :         if (ret != IF)
     260             :         {
     261             :         debug(0,("false...\n"));
     262           0 :         if (ret == IFFALSE)
     263           0 :             return(ELIFFALSE);
     264             :         else
     265           0 :             return(ELIFGUESSFALSE);
     266             :         }
     267             :         else
     268             :         {
     269             :         debug(0,("true...\n"));
     270           0 :         return(ELIF);
     271             :         }
     272             :     }
     273             : 
     274           0 :     if (ret < 0 || ! parse_it)
     275           0 :         return(ret);
     276             : 
     277             :     /*
     278             :      * now decide how to parse the directive, and do it.
     279             :      */
     280           0 :     while (*p == ' ' || *p == '\t')
     281           0 :         p++;
     282           0 :     switch (ret) {
     283             :     case IF:
     284             :         /*
     285             :          * parse an expression.
     286             :          */
     287           0 :         ret = zero_value(p, filep, file_red, symbols);
     288             :         debug(0,("%s, line %d: %s #if %s\n",
     289             :              file->i_file, filep->f_line, ret?"false":"true", p));
     290           0 :         break;
     291             :     case IFDEF:
     292             :     case IFNDEF:
     293             :         debug(0,("%s, line %d: #%s %s\n",
     294             :             file->i_file, filep->f_line, directives[ret], p));
     295             :     case UNDEF:
     296             :         /*
     297             :          * separate the name of a single symbol.
     298             :          */
     299           0 :         while (isalnum(*p) || *p == '_')
     300           0 :             *line++ = *p++;
     301           0 :         *line = '\0';
     302           0 :         break;
     303             :     case INCLUDE:
     304             :         debug(2,("%s, line %d: #include %s\n",
     305             :             file->i_file, filep->f_line, p));
     306             : 
     307             :         /* Support ANSI macro substitution */
     308             :         {
     309           0 :             char *sym = hash_lookup(p, symbols);
     310           0 :             while (sym)
     311             :             {
     312           0 :                 p = sym;
     313             :                 debug(3,("%s : #includes SYMBOL %s\n",
     314             :                             file->i_incstring,
     315             :                             sym));
     316             :                 /* mark file as having included a 'soft include' */
     317           0 :                 file->i_included_sym = TRUE;
     318           0 :                 sym = hash_lookup(p, symbols);
     319             :             }
     320             :         }
     321             : 
     322             :         /*
     323             :          * Separate the name of the include file.
     324             :          */
     325           0 :         while (*p && *p != '"' && *p != '<')
     326           0 :             p++;
     327           0 :         if (! *p)
     328           0 :             return(-2);
     329           0 :         if (*p++ == '"') {
     330           0 :             ret = INCLUDEDOT;
     331           0 :             while (*p && *p != '"')
     332           0 :                 *line++ = *p++;
     333             :         } else
     334           0 :             while (*p && *p != '>')
     335           0 :                 *line++ = *p++;
     336           0 :         *line = '\0';
     337           0 :         break;
     338             :     case DEFINE:
     339             :         /*
     340             :          * copy the definition back to the beginning of the line.
     341             :          */
     342           0 :         memmove (line, p, strlen(p));
     343           0 :         break;
     344             :     case ELSE:
     345             :     case ENDIF:
     346             :     case ELIF:
     347             :     case PRAGMA:
     348             :     case ERROR:
     349             :     case IDENT:
     350             :     case SCCS:
     351             :     case EJECT:
     352             :         debug(0,("%s, line %d: #%s\n",
     353             :             file->i_file, filep->f_line, directives[ret]));
     354             :         /*
     355             :          * nothing to do.
     356             :          */
     357           0 :         break;
     358             :     }
     359           0 :     return(ret);
     360             : }
     361             : 
     362             : /*
     363             :  * HACK! - so that we do not have to introduce 'symbols' in each cppsetup.c
     364             :  * function...  It's safe, functions from cppsetup.c don't return here.
     365             :  */
     366             : struct symhash *global_symbols = NULL;
     367             : 
     368           0 : char * isdefined( symbol )
     369             :     register char *symbol;
     370             : {
     371           0 :     return hash_lookup( symbol, global_symbols );
     372             : }
     373             : 
     374             : /*
     375             :  * Return type based on if the #if expression evaluates to 0
     376             :  */
     377           0 : int zero_value(exp, filep, file_red, symbols)
     378             :     register char   *exp;
     379             :     register struct filepointer *filep;
     380             :     register struct inclist *file_red;
     381             :     register struct symhash *symbols;
     382             : {
     383           0 :     global_symbols = symbols; /* HACK! see above */
     384           0 :     if (cppsetup(exp, filep, file_red))
     385           0 :         return(IFFALSE);
     386             :     else
     387           0 :         return(IF);
     388             : }
     389             : 
     390           0 : void define( def, symbols )
     391             :     char            *def;
     392             :     struct symhash **symbols;
     393             : {
     394             :     char *val;
     395             : 
     396             :     /* Separate symbol name and its value */
     397           0 :     val = def;
     398           0 :     while (isalnum(*val) || *val == '_')
     399           0 :         val++;
     400           0 :     if (*val)
     401           0 :         *val++ = '\0';
     402           0 :     while (*val == ' ' || *val == '\t')
     403           0 :         val++;
     404             : 
     405           0 :     if (!*val)
     406           0 :         val = "1";
     407           0 :     hash_define( def, val, symbols );
     408           0 : }
     409             : 
     410           0 : static int hash( str )
     411             :     register char *str;
     412             : {
     413             :     /* Hash (Kernighan and Ritchie) */
     414           0 :     register unsigned int hashval = 0;
     415             : 
     416           0 :     for ( ; *str; str++ )
     417             :     {
     418           0 :         hashval = ( hashval * SYMHASHSEED ) + ( *str );
     419             :     }
     420             : 
     421           0 :     return hashval & ( SYMHASHMEMBERS - 1 );
     422             : }
     423             : 
     424           0 : struct symhash *hash_copy( symbols )
     425             :     struct symhash *symbols;
     426             : {
     427             :     int i;
     428             :     struct symhash *newsym;
     429           0 :     if ( !symbols )
     430           0 :         return NULL;
     431             : 
     432           0 :     newsym = (struct symhash *) malloc( sizeof( struct symhash ) );
     433             : 
     434           0 :     for ( i = 0; i < SYMHASHMEMBERS; ++i )
     435             :     {
     436           0 :         if ( !symbols->s_pairs[ i ] )
     437           0 :             newsym->s_pairs[ i ] = NULL;
     438             :         else
     439             :         {
     440           0 :             struct pair *it = symbols->s_pairs[ i ];
     441           0 :             struct pair *nw = newsym->s_pairs[ i ] = (struct pair*) malloc( sizeof( struct pair ) );
     442           0 :             nw->p_name = it->p_name;
     443           0 :             nw->p_value = it->p_value;
     444           0 :             nw->p_next = NULL;
     445             : 
     446           0 :             while ( it->p_next )
     447             :             {
     448           0 :                 nw->p_next = (struct pair*) malloc( sizeof( struct pair ) );
     449           0 :                 it = it->p_next;
     450           0 :                 nw = nw->p_next;
     451           0 :                 nw->p_name = it->p_name;
     452           0 :                 nw->p_value = it->p_value;
     453           0 :                 nw->p_next = NULL;
     454             :             }
     455             :         }
     456             :     }
     457           0 :     return newsym;
     458             : }
     459             : 
     460           0 : void hash_free( symbols )
     461             :     struct symhash *symbols;
     462             : {
     463             :     int i;
     464             : 
     465           0 :     if ( !symbols )
     466           0 :         return;
     467             : 
     468           0 :     for ( i = 0; i < SYMHASHMEMBERS; ++i )
     469             :     {
     470           0 :         struct pair *it = symbols->s_pairs[ i ];
     471             :         struct pair *next;
     472           0 :         while ( it )
     473             :         {
     474           0 :             next = it->p_next;
     475           0 :             free( it );
     476           0 :             it = next;
     477             :         }
     478             :     }
     479           0 :     free( symbols->s_pairs );
     480             : }
     481             : 
     482           0 : void hash_define( name, val, symbols )
     483             :     char            *name, *val;
     484             :     struct symhash **symbols;
     485             : {
     486             :     int hashval;
     487             :     struct pair *it;
     488             : 
     489           0 :     if ( !symbols )
     490           0 :         return;
     491             : 
     492             :     /* Make space if it's needed */
     493           0 :     if ( *symbols == NULL )
     494             :     {
     495             :         int i;
     496             : 
     497           0 :         *symbols = (struct symhash *) malloc( sizeof( struct symhash ) );
     498           0 :         if ( *symbols == NULL )
     499           0 :             fatalerr( "malloc()/realloc() failure in insert_defn()\n" );
     500             : 
     501           0 :         for ( i = 0; i < SYMHASHMEMBERS; ++i )
     502           0 :             (*symbols)->s_pairs[i] = NULL;
     503             :     }
     504             : 
     505           0 :     hashval = hash( name );
     506           0 :     it = (*symbols)->s_pairs[ hashval ];
     507             : 
     508             :     /* Replace/insert the symbol */
     509           0 :     if ( it == NULL )
     510             :     {
     511           0 :         it = (*symbols)->s_pairs[ hashval ] = (struct pair*) malloc( sizeof( struct pair ) );
     512           0 :         it->p_name = copy( name );
     513           0 :         it->p_value = copy( val );
     514           0 :         it->p_next = NULL;
     515             :     }
     516           0 :     else if ( strcmp( it->p_name, name ) == 0 )
     517             :     {
     518           0 :         it->p_value = copy( val );
     519             :     }
     520             :     else
     521             :     {
     522           0 :         while ( it->p_next && ( strcmp( it->p_next->p_name, name ) != 0 ) )
     523             :         {
     524           0 :             it = it->p_next;
     525             :         }
     526           0 :         if ( it->p_next )
     527           0 :             it->p_next->p_name = copy( name );
     528             :         else
     529             :         {
     530           0 :             it->p_next = (struct pair*) malloc( sizeof( struct pair ) );
     531           0 :             it->p_next->p_name = copy( name );
     532           0 :             it->p_next->p_value = copy( val );
     533           0 :             it->p_next->p_next = NULL;
     534             :         }
     535             :     }
     536             : }
     537             : 
     538           0 : char *hash_lookup( symbol, symbols )
     539             :     char           *symbol;
     540             :     struct symhash *symbols;
     541             : {
     542             :     struct pair *it;
     543             : 
     544           0 :     if ( !symbols )
     545           0 :         return NULL;
     546             : 
     547           0 :     it = symbols->s_pairs[ hash( symbol ) ];
     548             : 
     549           0 :     while ( it && ( strcmp( it->p_name, symbol ) != 0 ) )
     550             :     {
     551           0 :         it = it->p_next;
     552             :     }
     553           0 :     if ( it )
     554           0 :         return it->p_value;
     555             : 
     556           0 :     return NULL;
     557             : }
     558             : 
     559           0 : void hash_undefine( symbol, symbols )
     560             :     char           *symbol;
     561             :     struct symhash *symbols;
     562             : {
     563             :     int hashval;
     564             :     struct pair *it;
     565             : 
     566           0 :     if ( !symbols )
     567           0 :         return;
     568             : 
     569           0 :     hashval = hash( symbol );
     570           0 :     it = symbols->s_pairs[ hashval ];
     571             : 
     572             :     /* Replace/insert the symbol */
     573           0 :     if ( it == NULL )
     574           0 :         return;
     575           0 :     else if ( strcmp( it->p_name, symbol ) == 0 )
     576             :     {
     577           0 :         if ( it->p_next )
     578             :         {
     579             :             struct pair *tmp;
     580           0 :             it->p_name = it->p_next->p_name;
     581           0 :             it->p_value = it->p_next->p_value;
     582           0 :             tmp = it->p_next->p_next;
     583           0 :             free( it->p_next );
     584           0 :             it->p_next = tmp;
     585             :         }
     586             :         else
     587             :         {
     588           0 :             free( it );
     589           0 :             symbols->s_pairs[ hashval ] = NULL;
     590             :         }
     591             :     }
     592             :     else
     593             :     {
     594           0 :         while ( it->p_next && ( strcmp( it->p_next->p_name, symbol ) != 0 ) )
     595             :         {
     596           0 :             it = it->p_next;
     597             :         }
     598           0 :         if ( it->p_next )
     599             :         {
     600           0 :             struct pair *tmp = it->p_next;
     601           0 :             it->p_next = it->p_next->p_next;
     602           0 :             free( tmp );
     603             :         }
     604             :     }
     605             : }
     606             : 
     607             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10