"Fossies" - the Fresh Open Source Software Archive

Member "cpostp1.c" (9 May 1995, 17644 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 "cpostp1.c" see the Fossies "Dox" file reference documentation.

    1 /*------------------------------------------------------------------
    2  * cpostp1.c : Pass 1 of cPost
    3  *------------------------------------------------------------------
    4  * 12-02-91 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 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
   17 
   18 /*------------------------------------------------------------------
   19  * add bracketing starts in front of braces
   20  *------------------------------------------------------------------*/
   21 static void AddLBracket(
   22    File *file,
   23    char *line,
   24    char *mask,
   25    int  *maxMask,
   26    Tok  *tok
   27    )
   28    {
   29    int  lIndent;
   30    int  rIndent;
   31    int  place;
   32    Tok *sib;
   33 
   34    /*---------------------------------------------------------------
   35     * see if matching bracket is on this line - if so, skip
   36     *---------------------------------------------------------------*/
   37    sib = tok->sib;
   38    if (sib && (sib->tok.line == tok->tok.line))
   39       return;
   40 
   41    /*---------------------------------------------------------------
   42     * find minimum indent of left and right brace
   43     *---------------------------------------------------------------*/
   44    lIndent = strspn(line," ");
   45    if (!tok->sib)
   46       place = lIndent;
   47    else
   48       {
   49       rIndent = strspn(file->line[sib->tok.line-1]," ");
   50       place = min(lIndent,rIndent);
   51       }
   52 
   53    /*---------------------------------------------------------------
   54     * if no indentation on { or }, don't bracket!
   55     *---------------------------------------------------------------*/
   56    if (!place)
   57       return;
   58 
   59    /*---------------------------------------------------------------
   60     * we'll bracket the column BEFORE this
   61     *---------------------------------------------------------------*/
   62    place--;
   63 
   64    /*---------------------------------------------------------------
   65     * set the mask, maxMask, and write bracket to line
   66     *---------------------------------------------------------------*/
   67    mask[place]++;
   68    *maxMask = max(place,*maxMask);
   69 
   70    if (' ' == line[place])
   71       line[place] = '\x01';
   72    }
   73 
   74 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
   75 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
   76 
   77 /*------------------------------------------------------------------
   78  * add bracketing ends
   79  *------------------------------------------------------------------*/
   80 static void AddRBracket(
   81    File *file,
   82    char *line,
   83    char *mask,
   84    int  *maxMask,
   85    Tok  *tok
   86    )
   87    {
   88    Tok *sib;
   89 
   90    /*---------------------------------------------------------------
   91     * see if matching bracket is on this line - if so, skip
   92     *---------------------------------------------------------------*/
   93    sib = tok->sib;
   94    if (sib && (sib->tok.line == tok->tok.line))
   95       return;
   96 
   97    /*---------------------------------------------------------------
   98     * safety valve
   99     *---------------------------------------------------------------*/
  100    if (-1 == *maxMask)
  101       return;
  102 
  103    /*---------------------------------------------------------
  104     * add end bracket to line
  105     *---------------------------------------------------------*/
  106    if (' ' == line[*maxMask])
  107       line[*maxMask] = '\x03';
  108 
  109    /*---------------------------------------------------------
  110     * reset mask and maxMask
  111     *---------------------------------------------------------*/
  112    mask[*maxMask]--;
  113    if (!mask[*maxMask])
  114       {
  115       *maxMask -= 1;
  116       while (-1 != *maxMask)
  117          if (mask[*maxMask])
  118             break;
  119          else
  120             *maxMask -= 1;
  121       }
  122    }
  123 
  124 
  125 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  126 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  127 
  128 /*------------------------------------------------------------------
  129  * add bracketing chars to line based on mask
  130  *------------------------------------------------------------------*/
  131 static char *AddMBrackets(
  132    File *file,
  133    char *line,
  134    char *mask,
  135    int   maxMask
  136    )
  137    {
  138    int   i;
  139 
  140    /*------------------------------------------------------------
  141     * see if we need to make the line longer
  142     *------------------------------------------------------------*/
  143    if (maxMask + 1 >= (int) strlen(line))
  144       {
  145       char *newLine;
  146 
  147       newLine = malloc(maxMask+3);
  148       if (!newLine)
  149          cPostError(1,"out of memory!!!");
  150 
  151       if ('\n' == line[strlen(line)-1])
  152          line[strlen(line)-1] = ' ';
  153 
  154       memset(newLine,' ',maxMask+1);
  155       newLine[maxMask+1] = '\n';
  156       newLine[maxMask+2] = 0;
  157       memcpy(newLine,line,strlen(line));
  158 
  159       free(line);
  160       line = newLine;
  161       }
  162 
  163    /*---------------------------------------------------------------
  164     * get number of first non-blank column
  165     *---------------------------------------------------------------*/
  166    maxMask = min(maxMask,(int)strspn(line," "));
  167 
  168    /*---------------------------------------------------------------
  169     * for each non-zero entry in mask, write bracket
  170     *---------------------------------------------------------------*/
  171    for (i=0; i<=maxMask; i++)
  172       {
  173       if (mask[i])
  174          if (' ' == line[i])
  175             line[i] = '\02';
  176       }
  177 
  178    return line;
  179    }
  180 
  181 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  182 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  183 
  184 /*------------------------------------------------------------------
  185  * strip trailing blanks off a line (that has a \n at the end!!)
  186  *------------------------------------------------------------------*/
  187 static void StripTrailingBlanks(
  188    char *line
  189    )
  190    {
  191    int slen;
  192 
  193    slen = strlen(line);
  194    if ('\n' != line[slen-1])
  195       {
  196       fprintf(stderr,"line found without carriage return!!\n");
  197       return;
  198       }
  199 
  200    line[slen-1] = ' ';
  201 
  202    while (*line && (' ' == line[slen-1]))
  203       {
  204       line[slen-1] = '\0';
  205       slen--;
  206       }
  207 
  208    line[slen] = '\n';
  209    }
  210 
  211 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  212 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  213 
  214 /*------------------------------------------------------------------
  215  * add function information to trees and lists
  216  *------------------------------------------------------------------*/
  217 static void AddFunctionPrototype(
  218    Info          *info,
  219    File          *file,
  220    char          *name
  221    )
  222    {
  223    Function *func;
  224 
  225    func = GetFunction(info,name);
  226 
  227    if (!ListFind(file->funcProList,&func))
  228       if (!ListAdd(file->funcProList,&func))
  229          cPostError(1,"error adding function prototype to list");
  230    }
  231 
  232 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  233 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  234 
  235 /*------------------------------------------------------------------
  236  * add function information to trees and lists
  237  *------------------------------------------------------------------*/
  238 static void AddFunctionDefinition(
  239    Info          *info,
  240    File          *file,
  241    char          *name,
  242    unsigned long  lineNo
  243    )
  244    {
  245    Function *func;
  246 
  247    func = GetFunction(info,name);
  248    if (!ListFind(file->funcDefList,&func))
  249       if (!ListAdd(file->funcDefList,&func))
  250          cPostError(1,"error adding function definition to list");
  251 
  252    func->fileName = file->name;
  253    func->lineNo   = lineNo;
  254    }
  255 
  256 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  257 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  258 
  259 /*------------------------------------------------------------------
  260  * add function information to trees and lists
  261  *------------------------------------------------------------------*/
  262 static void AddFunctionUsage(
  263    Info          *info,
  264    char          *calleeName,
  265    char          *callerName
  266    )
  267    {
  268    Function *caller;
  269    Function *callee;
  270 
  271    callee = GetFunction(info,calleeName);
  272    caller = GetFunction(info,callerName);
  273 
  274    if (!ListFind(caller->callsList,   &callee))
  275       if (!ListAdd(caller->callsList,   &callee))
  276          cPostError(1,"error adding function callee to list");
  277 
  278    if (!ListFind(callee->calledByList,&caller))
  279       if (!ListAdd(callee->calledByList,&caller))
  280          cPostError(1,"error adding function caller to list");
  281    }
  282 
  283 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  284 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  285 
  286 /*------------------------------------------------------------------
  287  *
  288  *------------------------------------------------------------------*/
  289 PageEject *addPageEject(
  290    File      *file,
  291    Tok       *tok,
  292    PageEject *pageJ
  293    )
  294    {
  295    PageEject     *new;
  296    unsigned long  lineNo;
  297    char          *line;
  298 
  299    /*---------------------------------------------------------------
  300     * get space for new node
  301     *---------------------------------------------------------------*/
  302    new = malloc(sizeof(PageEject));
  303    if (!new)
  304       cPostError(1,"out of memory!!!");
  305 
  306    /*---------------------------------------------------------------
  307     * link into list
  308     *---------------------------------------------------------------*/
  309    if (!pageJ)
  310       file->breakList = new;
  311    else
  312       pageJ->next     = new;
  313 
  314    new->next   = NULL;
  315    new->lineNo = file->lines;
  316 
  317    /*---------------------------------------------------------------
  318     * find first non blank line after token
  319     *---------------------------------------------------------------*/
  320    lineNo = tok->tok.line;
  321    if (lineNo >= file->lines)
  322       return new;
  323 
  324    line = file->line[lineNo];
  325    while (strspn(line," \n") == strlen(line))
  326       {
  327       lineNo++;
  328       if (lineNo >= file->lines)
  329          return new;
  330 
  331       line = file->line[lineNo];
  332       }
  333 
  334    new->lineNo = lineNo;
  335    return new;
  336    }
  337 
  338 /*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
  339 /*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
  340 
  341 /*------------------------------------------------------------------
  342  * pass 1 of cPost
  343  *  - expand tabs, put bracketing around braces, write output files
  344  *------------------------------------------------------------------*/
  345 int Pass1(
  346    File     *file,
  347    Info     *info
  348    )
  349    {
  350    Tok            *next;
  351    Tok            *def;
  352    char           *mask;
  353    char           *this;
  354    int             lineNo;
  355    int             i;
  356    FILE           *tempFile;
  357    Tok            *stack;
  358    Tok            *temp;
  359    int             maxMask;
  360    int             brackLvl;
  361    Tok            *lastSemi;
  362    int             doLastSemi;
  363    int             inFunc;
  364    PageEject      *pageJ;
  365 
  366    /*---------------------------------------------------------------
  367     * print status
  368     *---------------------------------------------------------------*/
  369    fprintf(stderr,"   Reading file %s\n",file->name);
  370 
  371    /*---------------------------------------------------------------
  372     * parse the file
  373     *---------------------------------------------------------------*/
  374    info->indent1 = 1;
  375 
  376    cParse(file,info);
  377 
  378    info->indent1 = 0;
  379 
  380    /*---------------------------------------------------------------
  381     * go down list, adding function information to function tree,
  382     * and computing bracket information
  383     *---------------------------------------------------------------*/
  384    next       = file->tokList;
  385    def        = NULL;
  386    stack      = NULL;
  387    lastSemi   = NULL;
  388    pageJ      = NULL;
  389    brackLvl   = 0;
  390    inFunc     = 0;
  391    doLastSemi = 1;
  392 
  393    while (next)
  394       {
  395       switch(next->extType)
  396          {
  397          /*---------------------------------------------------------
  398           * function stuff
  399           *---------------------------------------------------------*/
  400          case TOKEN_FUNPRO:
  401             AddFunctionPrototype(info,file,next->str);
  402             break;
  403 
  404          case TOKEN_FUNDEF:
  405             def = next;
  406             AddFunctionDefinition(info,file,next->str,next->tok.line);
  407             inFunc = 1;
  408 
  409             if (doLastSemi && lastSemi)
  410                {
  411                pageJ = addPageEject(file,lastSemi,pageJ);
  412 
  413                lastSemi   = NULL;
  414                doLastSemi = 0;
  415                }
  416 
  417             break;
  418 
  419          case TOKEN_FUNUSE:
  420             AddFunctionUsage(info,next->str,def ? def->str : "");
  421             break;
  422 
  423          /*---------------------------------------------------------
  424           * semicolons for page breaks
  425           *---------------------------------------------------------*/
  426          case TOKEN_SCOLON:
  427          case TOKEN_PREPROC:
  428             if (doLastSemi)
  429                lastSemi = next;
  430             break;
  431 
  432          /*---------------------------------------------------------
  433           * bracket stuff
  434           *---------------------------------------------------------*/
  435          case TOKEN_LBRACE:
  436             brackLvl++;
  437             next->sib   = NULL;
  438             next->flags = 0;
  439 
  440             /*---------------------------------------------------
  441              * put { on the stack
  442              *---------------------------------------------------*/
  443             next->sib   = stack;
  444             stack       = next;
  445             next->flags = 1;
  446 
  447             break;
  448 
  449          case TOKEN_RBRACE:
  450             next->sib   = NULL;
  451             next->flags = 0;
  452 
  453                next->extType = TOKEN_RBRACE;
  454 
  455             /*---------------------------------------------------
  456              * remove { from stack, point { to } and } to {
  457              *---------------------------------------------------*/
  458             if (!stack)
  459                fprintf(stderr,"unmatched } on line %ld\n",next->tok.line);
  460             else
  461                {
  462                temp = stack;
  463                stack = stack->sib;
  464 
  465                temp->sib   = next;
  466                next->sib   = temp;
  467                next->flags = 1;
  468                }
  469 
  470             if (brackLvl > 0)
  471                brackLvl--;
  472 
  473             /*------------------------------------------------------
  474              * add conditional break, if it's time
  475              *------------------------------------------------------*/
  476             if (inFunc && !brackLvl)
  477                {
  478                pageJ = addPageEject(file,next,pageJ);
  479 
  480                doLastSemi = 0;
  481                }
  482 
  483             break;
  484          }
  485 
  486       next = next->next;
  487       }
  488 
  489    /*---------------------------------------------------------------
  490     * check for extra { on the stack
  491     *---------------------------------------------------------------*/
  492    while (stack)
  493       {
  494       fprintf(stderr,"unmatched { on line %ld\n",stack->tok.line);
  495       stack = stack->sib;
  496       }
  497 
  498    /*---------------------------------------------------------------
  499     * now, let's add the bracketing characters
  500     *---------------------------------------------------------------*/
  501 
  502    /*---------------------------------------------------------------
  503     * initialize mask
  504     *---------------------------------------------------------------*/
  505    mask = malloc(file->maxLineLen+1);
  506    if (!mask)
  507       cPostError(1,"out of memory!!!");
  508 
  509    memset(mask,0,file->maxLineLen+1);
  510 
  511    /*---------------------------------------------------------------
  512     * process each line
  513     *---------------------------------------------------------------*/
  514    next    = file->tokList;
  515    maxMask = -1;
  516    for (lineNo=0; lineNo < (int)file->lines; lineNo++)
  517       {
  518       this = file->line[lineNo];
  519 
  520       /*------------------------------------------------------------
  521        * go to next token in this line
  522        *------------------------------------------------------------*/
  523       while (next && (next->tok.line <  (unsigned long)(lineNo + 1)))
  524          next = next->next;
  525 
  526       /*------------------------------------------------------------
  527        * add beginning and ending brackets
  528        *------------------------------------------------------------*/
  529       if (info->oBrack)
  530          {
  531          while (next && (next->tok.line == (unsigned long)(lineNo + 1)))
  532             {
  533             if      ((TOKEN_LBRACE == next->extType) && (next->flags))
  534                AddLBracket(file,this,mask,&maxMask,next);
  535 
  536             else if ((TOKEN_RBRACE == next->extType) && (next->flags))
  537                AddRBracket(file,this,mask,&maxMask,next);
  538 
  539             next = next->next;
  540             }
  541          }
  542 
  543       /*------------------------------------------------------------
  544        * add middle brackets
  545        *------------------------------------------------------------*/
  546       file->line[lineNo] = AddMBrackets(file,this,mask,maxMask);
  547       }
  548 
  549    /*---------------------------------------------------------------
  550     * generate temp file name
  551     *---------------------------------------------------------------*/
  552    file->tempName = TempFileName(&tempFile,info);
  553 
  554    /*---------------------------------------------------------------
  555     * write file to temp file
  556     *---------------------------------------------------------------*/
  557    for (i=0; i<(int)file->lines; i++)
  558       fputs(file->line[i],tempFile);
  559 
  560    fclose(tempFile);
  561 
  562    /*---------------------------------------------------------------
  563     * let's clean up all the memory we used
  564     *---------------------------------------------------------------*/
  565    free(mask);
  566 
  567    /*---------------------------------------------------------------
  568     * clean out our data structures
  569     *---------------------------------------------------------------*/
  570    cParseDone(file,info);
  571 
  572    return 0;
  573    }
  574