"Fossies" - the Fresh Open Source Software Archive

Member "cpostpar.c" (9 May 1995, 13681 Bytes) of package /linux/misc/old/cpost.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "cpostpar.c" see the Fossies "Dox" file reference documentation.

    1 /*------------------------------------------------------------------
    2  * cPostPar.c : higher level parser for cPost
    3  *------------------------------------------------------------------
    4  * 03-19-92 originally by Patrick J. Mueller
    5  * 12-03-92 converted from cBook to cPost
    6  *------------------------------------------------------------------*/
    7 
    8 #include <stdio.h>
    9 #include <stdlib.h>
   10 #include <string.h>
   11 
   12 #include "ctok.h"
   13 #include "cpost.h"
   14 
   15 /*------------------------------------------------------------------
   16  * is string a C keyword
   17  *------------------------------------------------------------------*/
   18 static int IsKeyword(
   19    Info *info,
   20    char *str
   21    )
   22    {
   23    if (HashFind(info->reservedHash,&str))
   24       return 1;
   25    else
   26       return 0;
   27    }
   28 
   29 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
   30 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
   31 
   32 /*------------------------------------------------------------------
   33  * add function information to tokens in list
   34  *------------------------------------------------------------------*/
   35 static void AddFunctionInfoToTokens(
   36    File *file
   37    )
   38    {
   39    Tok *next;
   40    Tok *func;
   41 
   42    /*---------------------------------------------------------------
   43     * loop through the file
   44     *---------------------------------------------------------------*/
   45    next = file->tokList;
   46    while (NULL != next)
   47       {
   48       /*------------------------------------------------------------
   49        * continue reading till we have an identifier
   50        *------------------------------------------------------------*/
   51       if (TOKEN_IDENT != next->extType)
   52          {
   53          next = next->next;
   54          continue;
   55          }
   56 
   57       /*---------------------------------------------------------
   58        * if next token is (, this is a function name!
   59        *---------------------------------------------------------*/
   60       func = next;
   61       next = next->next;
   62       if (NULL == next)
   63          return;
   64 
   65       while ((TOKEN_COMMENT == next->extType) ||
   66              (TOKEN_PREPROC == next->extType))
   67          {
   68          next = next->next;
   69 
   70          if (NULL == next)
   71             return;
   72          }
   73 
   74       if (TOKEN_LPAREN == next->extType)
   75          {
   76 
   77          /*------------------------------------------------------
   78           * if we're in braces, it's usage
   79           *------------------------------------------------------*/
   80          if (next->nestBrace > 0)
   81             func->extType = TOKEN_FUNUSE;
   82 
   83          /*------------------------------------------------------
   84           * otherwise it's a prototype or definition
   85           *------------------------------------------------------*/
   86          else
   87             {
   88             /*---------------------------------------------------
   89              * get to the top level parenthesis
   90              *---------------------------------------------------*/
   91             while (next->nestParen > 0)
   92                {
   93                next = next->next;
   94                if (NULL == next)
   95                   return;
   96                }
   97 
   98             /*---------------------------------------------------
   99              * if next token is ;, it's a prototype, otherwise
  100              * it's a definition - we'll assume it's a prototype
  101              * though
  102              *---------------------------------------------------*/
  103             func->extType = TOKEN_FUNPRO;
  104 
  105             next = next->next;
  106             if (NULL == next)
  107                return;
  108 
  109             while ((TOKEN_COMMENT == next->extType) ||
  110                    (TOKEN_PREPROC == next->extType))
  111                {
  112                next = next->next;
  113 
  114                if (NULL == next)
  115                   return;
  116                }
  117 
  118             if      (TOKEN_SCOLON == next->extType)
  119                func->extType = TOKEN_FUNPRO;
  120             else if (TOKEN_COMMA  == next->extType)
  121                func->extType = TOKEN_FUNPRO;
  122             else
  123                func->extType = TOKEN_FUNDEF;
  124             }
  125          }
  126       }
  127    }
  128 
  129 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  130 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  131 
  132 /*------------------------------------------------------------------
  133  * function that walks over hash table - for each thing in hash
  134  * table, see if it's a function - if not, release the strings
  135  * storage - otherwise add to the info hash table
  136  *------------------------------------------------------------------*/
  137 static int CleanUpHashTableWalker(
  138    char **ident,
  139    Info  *info
  140    )
  141    {
  142    Function  func;
  143    Function *found;
  144 
  145    func.name = *ident;
  146 
  147    /*---------------------------------------------------------------
  148     * see if it's a function
  149     *---------------------------------------------------------------*/
  150    found = ListFind(info->funcTree,&func);
  151 
  152    /*---------------------------------------------------------------
  153     * if not found, release string storage
  154     *---------------------------------------------------------------*/
  155    if (!found)
  156       {
  157       free(*ident);
  158       return 0;
  159       }
  160 
  161    /*---------------------------------------------------------------
  162     * see if it's already in the info hash table
  163     *---------------------------------------------------------------*/
  164    if (HashFind(info->identHash,ident))
  165       {
  166       free(*ident);
  167       return 0;
  168       }
  169 
  170    /*---------------------------------------------------------------
  171     * if not, add it
  172     *---------------------------------------------------------------*/
  173    if (!HashAdd(info->identHash,ident))
  174       cPostError(1,"error adding identifier to global hash table");
  175 
  176    return 0;
  177    }
  178 
  179 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  180 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  181 
  182 /*------------------------------------------------------------------
  183  * parse the file for functions
  184  *------------------------------------------------------------------*/
  185 void cParse(
  186    File     *file,
  187    Info     *info
  188    )
  189    {
  190    void          *hTokenizer;
  191    Tok           *next;
  192    Tok           *prev;
  193    Tok           *fnc;
  194    static char    tmpIdent [MAX_IDENT_LEN + 1];
  195    char          *ptmpIdent  =   tmpIdent;
  196    char         **pptmpIdent = &ptmpIdent;
  197    char         **tempStr;
  198 
  199    /*---------------------------------------------------------------
  200     * read the file
  201     *---------------------------------------------------------------*/
  202    if (NULL == FileReadLines(info,file))
  203       cPostError(1,"unable to read file");
  204 
  205    file->identHash = HashCreate(sizeof(char *),
  206                                 1000,
  207                                 (HashFunc *)IdentHash,
  208                                 (ListCompareFunc *)IdentCompare,
  209                                 cPostNoMem);
  210    if (!file->identHash)
  211       cPostError(1,"error creating hash table");
  212 
  213    /*------------------------------------------------------------
  214     * initialize tokenization
  215     *------------------------------------------------------------*/
  216    hTokenizer      = CTokInit(GetBlockOfFile,file);
  217    if (!hTokenizer)
  218       cPostError(1,"error initializing tokenization");
  219 
  220    file->tokList   = NULL;
  221    next            = malloc(sizeof(Tok));
  222    if (!next)
  223       cPostError(1,"out of memory!!!");
  224 
  225    next->next      = NULL;
  226    next->nestParen = 0;
  227    next->nestBrace = 0;
  228    next->str       = NULL;
  229 
  230    prev = NULL;
  231 
  232    fnc = NULL;
  233 
  234    /*------------------------------------------------------------
  235     * build list of tokens
  236     *------------------------------------------------------------*/
  237    CTokGet(hTokenizer,&(next->tok));
  238    while (TOKEN_EOF != next->tok.type)
  239       {
  240 
  241       /*------------------------------------------------------------
  242        * get a little more info
  243        *------------------------------------------------------------*/
  244       next->extType = next->tok.type;
  245 
  246       if (TOKEN_OPER == next->extType)
  247          {
  248          switch(next->tok.ident[0])
  249             {
  250             case '{':
  251                next->extType = TOKEN_LBRACE;
  252                next->nestBrace++;
  253 
  254                if (next->nestParen)
  255                   {
  256                   fprintf(stderr,"unmatched ( on or before "
  257                                  "line %ld\n",next->tok.line);
  258                   next->nestParen = 0;
  259                   }
  260                break;
  261 
  262             case '}':
  263                next->extType = TOKEN_RBRACE;
  264                next->nestBrace--;
  265 
  266                if (next->nestParen)
  267                   {
  268                   fprintf(stderr,"unmatched ( on or before "
  269                                  "line %ld\n",next->tok.line);
  270                   next->nestParen = 0;
  271                   }
  272                break;
  273 
  274             case '(':
  275                next->extType = TOKEN_LPAREN;
  276                next->nestParen++;
  277 
  278                /*---------------------------------------------------
  279                 * add the identifier before this, if there was one
  280                 *---------------------------------------------------*/
  281                if (!fnc)
  282                   break;
  283 
  284                /*------------------------------------------------------
  285                 * get string from hash or add it
  286                 *------------------------------------------------------*/
  287                tempStr = HashFind(file->identHash,pptmpIdent);
  288                if (tempStr)
  289                   fnc->str = *tempStr;
  290                else
  291                   {
  292                   fnc->str = malloc(1+strlen(tmpIdent));
  293                   if (!fnc->str)
  294                      cPostError(1,"out of memory!!!");
  295 
  296                   strcpy(fnc->str,tmpIdent);
  297                   if (!HashAdd(file->identHash,&(fnc->str)))
  298                      cPostError(1,"error adding identifier to file hash table");
  299                   }
  300 
  301                fnc = NULL;
  302                break;
  303 
  304             case ')':
  305                next->extType = TOKEN_RPAREN;
  306 
  307                if (next->nestParen)
  308                   next->nestParen--;
  309                else
  310                   {
  311                   fprintf(stderr,"unnested ) on "
  312                                  "line %ld\n",next->tok.line);
  313                   next->nestParen = 0;
  314                   }
  315 
  316                break;
  317 
  318             case ';':
  319                next->extType = TOKEN_SCOLON;
  320                break;
  321 
  322             case ',':
  323                next->extType = TOKEN_COMMA;
  324                break;
  325             }
  326          }
  327 
  328       else if (TOKEN_IDENT == next->extType)
  329          {
  330 
  331          if (IsKeyword(info,next->tok.ident))
  332             next->extType = TOKEN_RESER;
  333          else
  334             {
  335             strcpy(tmpIdent,next->tok.ident);
  336             fnc = next;
  337             }
  338          }
  339 
  340       /*------------------------------------------------------------
  341        * link into list
  342        *------------------------------------------------------------*/
  343       if (NULL == file->tokList)
  344          file->tokList = next;
  345       else
  346          prev->next = next;
  347 
  348       /*------------------------------------------------------------
  349        * get next token
  350        *------------------------------------------------------------*/
  351       prev            = next;
  352       next            = malloc(sizeof(Tok));
  353       if (!next)
  354          cPostError(1,"out of memory!!!");
  355 
  356       next->next      = NULL;
  357       next->nestParen = prev->nestParen;
  358       next->nestBrace = prev->nestBrace;
  359       next->str       = NULL;
  360 
  361       CTokGet(hTokenizer,&(next->tok));
  362       }
  363 
  364    /*---------------------------------------------------------------
  365     * free the last hanging token
  366     *---------------------------------------------------------------*/
  367    free(next);
  368 
  369    /*------------------------------------------------------------
  370     * terminate tokenization
  371     *------------------------------------------------------------*/
  372    CTokTerm(hTokenizer);
  373 
  374    /*---------------------------------------------------------------
  375     * analyze the tokens
  376     *---------------------------------------------------------------*/
  377    AddFunctionInfoToTokens(file);
  378    }
  379 
  380 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  381 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  382 
  383 /*------------------------------------------------------------------
  384  * clean up after parsing file for functions
  385  *------------------------------------------------------------------*/
  386 void cParseDone(
  387    File     *file,
  388    Info     *info
  389    )
  390    {
  391    Tok *tok;
  392    Tok *next;
  393    int  i;
  394 
  395    /*---------------------------------------------------------------
  396     * walk over old hash table, adding functions to info hash table
  397     * and freeing non-function strings
  398     *---------------------------------------------------------------*/
  399    HashIterate(file->identHash,(ListIterateFunc *)CleanUpHashTableWalker,info);
  400 
  401    /*---------------------------------------------------------------
  402     * destroy the file hash table
  403     *---------------------------------------------------------------*/
  404    HashDestroy(file->identHash);
  405 
  406    /*---------------------------------------------------------------
  407     * now clean up token list
  408     *---------------------------------------------------------------*/
  409    tok = file->tokList;
  410 
  411    /*---------------------------------------------------------------
  412     * loop through tokens and free 'um
  413     *---------------------------------------------------------------*/
  414    while (tok)
  415       {
  416       next = tok->next;
  417       free(tok);
  418       tok = next;
  419       }
  420 
  421    /*---------------------------------------------------------------
  422     * release file storage
  423     *---------------------------------------------------------------*/
  424    for (i=0; i<(int)file->lines; i++)
  425       free(file->line[i]);
  426 
  427    free(file->line);
  428    }