LCOV - code coverage report
Current view: top level - libreoffice/soltools/mkdepend - parse.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 181 240 75.4 %
Date: 2012-12-27 Functions: 11 12 91.7 %
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          60 : 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         447 :     while ((line = get_line(filep))) {
      51         376 :         switch(type = deftype(line, filep, file_red, file, TRUE, symbols)) {
      52             :         case IF:
      53             :         doif:
      54           9 :             type = find_includes(filep, file,
      55             :                 file_red, recursion+1, failOK, incCollection, symbols);
      56          20 :             while ((type == ELIF) || (type == ELIFFALSE) ||
      57             :                    (type == ELIFGUESSFALSE))
      58           2 :                 type = gobble(filep, file, file_red, symbols);
      59           9 :             if (type == ELSE)
      60           5 :                 gobble(filep, file, file_red, symbols);
      61           9 :             break;
      62             :         case IFFALSE:
      63             :         case IFGUESSFALSE:
      64             :             doiffalse:
      65          33 :             if (type == IFGUESSFALSE || type == ELIFGUESSFALSE)
      66           0 :                 recfailOK = TRUE;
      67             :             else
      68          33 :                 recfailOK = failOK;
      69          33 :             type = gobble(filep, file, file_red, symbols);
      70          33 :             if (type == ELSE)
      71          16 :                 find_includes(filep, file,
      72             :                       file_red, recursion+1, recfailOK, incCollection, symbols);
      73          17 :             else if (type == ELIF)
      74           3 :                 goto doif;
      75          14 :             else if ((type == ELIFFALSE) || (type == ELIFGUESSFALSE))
      76             :                 goto doiffalse;
      77          23 :             break;
      78             :         case IFDEF:
      79             :         case IFNDEF:
      80          43 :             if ((type == IFDEF && hash_lookup(line, symbols))
      81          42 :              || (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          18 :                 type = find_includes(filep, file,
      87             :                     file_red, recursion+1, failOK, incCollection, symbols);
      88          36 :                 while (type == ELIF || type == ELIFFALSE || type == ELIFGUESSFALSE)
      89           0 :                     type = gobble(filep, file, file_red, symbols);
      90          36 :                 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          25 :                 type = gobble(filep, file, file_red, symbols);
      99          25 :                 if (type == ELSE)
     100           6 :                     find_includes(filep, file,
     101             :                         file_red, recursion + 1, failOK, incCollection, symbols);
     102          19 :                 else if (type == ELIF)
     103           2 :                         goto doif;
     104          17 :                 else if (type == ELIFFALSE || type == ELIFGUESSFALSE)
     105             :                         goto doiffalse;
     106             :             }
     107          41 :             break;
     108             :         case ELSE:
     109             :         case ELIFFALSE:
     110             :         case ELIFGUESSFALSE:
     111             :         case ELIF:
     112           6 :             if (!recursion)
     113           0 :                 gobble(filep, file, file_red, symbols);
     114             :         case ENDIF:
     115          49 :             if (recursion)
     116          49 :                 return(type);
     117             :         case DEFINE:
     118         220 :             define(line, &symbols);
     119         220 :             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          16 :             add_include(filep, file, file_red, line, FALSE, failOK, incCollection, symbols);
     130          16 :             break;
     131             :         case INCLUDEDOT:
     132          18 :             add_include(filep, file, file_red, line, TRUE, failOK, incCollection, symbols);
     133          18 :             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          11 :     return(-1);
     161             : }
     162             : 
     163          78 : 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         253 :     while ((line = get_line(filep))) {
     172         175 :         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           9 :             type = gobble(filep, file, file_red, symbols);
     179          18 :             while ((type == ELIF) || (type == ELIFFALSE) ||
     180             :                    (type == ELIFGUESSFALSE))
     181           0 :                 type = gobble(filep, file, file_red, symbols);
     182           9 :             if (type == ELSE)
     183           4 :                     (void)gobble(filep, file, file_red, symbols);
     184           9 :             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          66 :             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          88 :             break;
     201             :         case ELIF:
     202             :         case ELIFFALSE:
     203             :         case ELIFGUESSFALSE:
     204          12 :             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         551 : 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         551 :     directive=line+1;
     232        1425 :     while (*directive == ' ' || *directive == '\t')
     233         323 :         directive++;
     234             : 
     235         551 :     p = directive;
     236        4107 :     while (*p >= 'a' && *p <= 'z')
     237        3005 :         p++;
     238         551 :     savechar = *p;
     239         551 :     *p = '\0';
     240         551 :     ret = match(directive, directives);
     241         551 :     *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         551 :     if (ret == ELIF && !parse_it)
     250             :     {
     251          37 :         while (*p == ' ' || *p == '\t')
     252          13 :         p++;
     253             :         /*
     254             :          * parse an expression.
     255             :          */
     256             :         debug(0,("%s, line %d: #elif %s ",
     257             :            file->i_file, filep->f_line, p));
     258          12 :         ret = zero_value(p, filep, file_red, symbols);
     259          12 :         if (ret != IF)
     260             :         {
     261             :         debug(0,("false...\n"));
     262           7 :         if (ret == IFFALSE)
     263           7 :             return(ELIFFALSE);
     264             :         else
     265           0 :             return(ELIFGUESSFALSE);
     266             :         }
     267             :         else
     268             :         {
     269             :         debug(0,("true...\n"));
     270           5 :         return(ELIF);
     271             :         }
     272             :     }
     273             : 
     274         539 :     if (ret < 0 || ! parse_it)
     275         163 :         return(ret);
     276             : 
     277             :     /*
     278             :      * now decide how to parse the directive, and do it.
     279             :      */
     280        1280 :     while (*p == ' ' || *p == '\t')
     281         528 :         p++;
     282         376 :     switch (ret) {
     283             :     case IF:
     284             :         /*
     285             :          * parse an expression.
     286             :          */
     287          30 :         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          30 :         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         563 :         while (isalnum(*p) || *p == '_')
     300         477 :             *line++ = *p++;
     301          43 :         *line = '\0';
     302          43 :         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          34 :             char *sym = hash_lookup(p, symbols);
     310          68 :             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          68 :         while (*p && *p != '"' && *p != '<')
     326           0 :             p++;
     327          34 :         if (! *p)
     328           0 :             return(-2);
     329          34 :         if (*p++ == '"') {
     330          18 :             ret = INCLUDEDOT;
     331         276 :             while (*p && *p != '"')
     332         240 :                 *line++ = *p++;
     333             :         } else
     334         174 :             while (*p && *p != '>')
     335         142 :                 *line++ = *p++;
     336          34 :         *line = '\0';
     337          34 :         break;
     338             :     case DEFINE:
     339             :         /*
     340             :          * copy the definition back to the beginning of the line.
     341             :          */
     342         220 :         memmove (line, p, strlen(p));
     343         220 :         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          49 :         break;
     358             :     }
     359         376 :     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          68 : char * isdefined( symbol )
     369             :     register char *symbol;
     370             : {
     371          68 :     return hash_lookup( symbol, global_symbols );
     372             : }
     373             : 
     374             : /*
     375             :  * Return type based on if the #if expression evaluates to 0
     376             :  */
     377          42 : 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          42 :     global_symbols = symbols; /* HACK! see above */
     384          42 :     if (cppsetup(exp, filep, file_red))
     385          33 :         return(IFFALSE);
     386             :     else
     387           9 :         return(IF);
     388             : }
     389             : 
     390         264 : void define( def, symbols )
     391             :     char            *def;
     392             :     struct symhash **symbols;
     393             : {
     394             :     char *val;
     395             : 
     396             :     /* Separate symbol name and its value */
     397         264 :     val = def;
     398        6728 :     while (isalnum(*val) || *val == '_')
     399        6200 :         val++;
     400         264 :     if (*val)
     401         213 :         *val++ = '\0';
     402        2581 :     while (*val == ' ' || *val == '\t')
     403        2053 :         val++;
     404             : 
     405         264 :     if (!*val)
     406          51 :         val = "1";
     407         264 :     hash_define( def, val, symbols );
     408         264 : }
     409             : 
     410         413 : static int hash( str )
     411             :     register char *str;
     412             : {
     413             :     /* Hash (Kernighan and Ritchie) */
     414         413 :     register unsigned int hashval = 0;
     415             : 
     416        8388 :     for ( ; *str; str++ )
     417             :     {
     418        7975 :         hashval = ( hashval * SYMHASHSEED ) + ( *str );
     419             :     }
     420             : 
     421         413 :     return hashval & ( SYMHASHMEMBERS - 1 );
     422             : }
     423             : 
     424           2 : struct symhash *hash_copy( symbols )
     425             :     struct symhash *symbols;
     426             : {
     427             :     int i;
     428             :     struct symhash *newsym;
     429           2 :     if ( !symbols )
     430           0 :         return NULL;
     431             : 
     432           2 :     newsym = (struct symhash *) malloc( sizeof( struct symhash ) );
     433             : 
     434         130 :     for ( i = 0; i < SYMHASHMEMBERS; ++i )
     435             :     {
     436         128 :         if ( !symbols->s_pairs[ i ] )
     437          88 :             newsym->s_pairs[ i ] = NULL;
     438             :         else
     439             :         {
     440          40 :             struct pair *it = symbols->s_pairs[ i ];
     441          40 :             struct pair *nw = newsym->s_pairs[ i ] = (struct pair*) malloc( sizeof( struct pair ) );
     442          40 :             nw->p_name = it->p_name;
     443          40 :             nw->p_value = it->p_value;
     444          40 :             nw->p_next = NULL;
     445             : 
     446          88 :             while ( it->p_next )
     447             :             {
     448           8 :                 nw->p_next = (struct pair*) malloc( sizeof( struct pair ) );
     449           8 :                 it = it->p_next;
     450           8 :                 nw = nw->p_next;
     451           8 :                 nw->p_name = it->p_name;
     452           8 :                 nw->p_value = it->p_value;
     453           8 :                 nw->p_next = NULL;
     454             :             }
     455             :         }
     456             :     }
     457           2 :     return newsym;
     458             : }
     459             : 
     460           2 : void hash_free( symbols )
     461             :     struct symhash *symbols;
     462             : {
     463             :     int i;
     464             : 
     465           2 :     if ( !symbols )
     466           2 :         return;
     467             : 
     468         130 :     for ( i = 0; i < SYMHASHMEMBERS; ++i )
     469             :     {
     470         128 :         struct pair *it = symbols->s_pairs[ i ];
     471             :         struct pair *next;
     472         524 :         while ( it )
     473             :         {
     474         268 :             next = it->p_next;
     475         268 :             free( it );
     476         268 :             it = next;
     477             :         }
     478             :     }
     479           2 :     free( symbols->s_pairs );
     480             : }
     481             : 
     482         268 : void hash_define( name, val, symbols )
     483             :     char            *name, *val;
     484             :     struct symhash **symbols;
     485             : {
     486             :     int hashval;
     487             :     struct pair *it;
     488             : 
     489         268 :     if ( !symbols )
     490         268 :         return;
     491             : 
     492             :     /* Make space if it's needed */
     493         268 :     if ( *symbols == NULL )
     494             :     {
     495             :         int i;
     496             : 
     497           2 :         *symbols = (struct symhash *) malloc( sizeof( struct symhash ) );
     498           2 :         if ( *symbols == NULL )
     499           0 :             fatalerr( "malloc()/realloc() failure in insert_defn()\n" );
     500             : 
     501         130 :         for ( i = 0; i < SYMHASHMEMBERS; ++i )
     502         128 :             (*symbols)->s_pairs[i] = NULL;
     503             :     }
     504             : 
     505         268 :     hashval = hash( name );
     506         268 :     it = (*symbols)->s_pairs[ hashval ];
     507             : 
     508             :     /* Replace/insert the symbol */
     509         268 :     if ( it == NULL )
     510             :     {
     511          81 :         it = (*symbols)->s_pairs[ hashval ] = (struct pair*) malloc( sizeof( struct pair ) );
     512          81 :         it->p_name = copy( name );
     513          81 :         it->p_value = copy( val );
     514          81 :         it->p_next = NULL;
     515             :     }
     516         187 :     else if ( strcmp( it->p_name, name ) == 0 )
     517             :     {
     518           0 :         it->p_value = copy( val );
     519             :     }
     520             :     else
     521             :     {
     522         701 :         while ( it->p_next && ( strcmp( it->p_next->p_name, name ) != 0 ) )
     523             :         {
     524         327 :             it = it->p_next;
     525             :         }
     526         187 :         if ( it->p_next )
     527           0 :             it->p_next->p_name = copy( name );
     528             :         else
     529             :         {
     530         187 :             it->p_next = (struct pair*) malloc( sizeof( struct pair ) );
     531         187 :             it->p_next->p_name = copy( name );
     532         187 :             it->p_next->p_value = copy( val );
     533         187 :             it->p_next->p_next = NULL;
     534             :         }
     535             :     }
     536             : }
     537             : 
     538         145 : char *hash_lookup( symbol, symbols )
     539             :     char           *symbol;
     540             :     struct symhash *symbols;
     541             : {
     542             :     struct pair *it;
     543             : 
     544         145 :     if ( !symbols )
     545           0 :         return NULL;
     546             : 
     547         145 :     it = symbols->s_pairs[ hash( symbol ) ];
     548             : 
     549         420 :     while ( it && ( strcmp( it->p_name, symbol ) != 0 ) )
     550             :     {
     551         130 :         it = it->p_next;
     552             :     }
     553         145 :     if ( it )
     554          17 :         return it->p_value;
     555             : 
     556         128 :     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