LCOV - code coverage report
Current view: top level - src/tools/pg_bsd_indent - parse.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 114 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 2 0
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-
       2              :  * Copyright (c) 1985 Sun Microsystems, Inc.
       3              :  * Copyright (c) 1980, 1993
       4              :  *      The Regents of the University of California.  All rights reserved.
       5              :  * All rights reserved.
       6              :  *
       7              :  * Redistribution and use in source and binary forms, with or without
       8              :  * modification, are permitted provided that the following conditions
       9              :  * are met:
      10              :  * 1. Redistributions of source code must retain the above copyright
      11              :  *    notice, this list of conditions and the following disclaimer.
      12              :  * 2. Redistributions in binary form must reproduce the above copyright
      13              :  *    notice, this list of conditions and the following disclaimer in the
      14              :  *    documentation and/or other materials provided with the distribution.
      15              :  * 3. Neither the name of the University nor the names of its contributors
      16              :  *    may be used to endorse or promote products derived from this software
      17              :  *    without specific prior written permission.
      18              :  *
      19              :  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      20              :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      21              :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      22              :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      23              :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      24              :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      25              :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      26              :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      27              :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      28              :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      29              :  * SUCH DAMAGE.
      30              :  */
      31              : 
      32              : #if 0
      33              : #ifndef lint
      34              : static char sccsid[] = "@(#)parse.c        8.1 (Berkeley) 6/6/93";
      35              : #endif /* not lint */
      36              : #endif
      37              : 
      38              : #include "c.h"
      39              : 
      40              : #include <err.h>
      41              : #include <stdio.h>
      42              : #include "indent_globs.h"
      43              : #include "indent_codes.h"
      44              : #include "indent.h"
      45              : 
      46              : static void reduce(void);
      47              : 
      48              : void
      49            0 : parse(int tk) /* tk: the code for the construct scanned */
      50              : {
      51            0 :     int         i;
      52              : 
      53              : #ifdef debug
      54              :     printf("%2d - %s\n", tk, token);
      55              : #endif
      56              : 
      57            0 :     while (ps.p_stack[ps.tos] == ifhead && tk != elselit) {
      58              :         /* true if we have an if without an else */
      59            0 :         ps.p_stack[ps.tos] = stmt;      /* apply the if(..) stmt ::= stmt
      60              :                                          * reduction */
      61            0 :         reduce();               /* see if this allows any reduction */
      62              :     }
      63              : 
      64              : 
      65            0 :     switch (tk) {               /* go on and figure out what to do with the
      66              :                                  * input */
      67              : 
      68              :     case decl:                  /* scanned a declaration word */
      69            0 :         ps.search_brace = btype_2;
      70              :         /* indicate that following brace should be on same line */
      71            0 :         if (ps.p_stack[ps.tos] != decl) {       /* only put one declaration
      72              :                                                  * onto stack */
      73            0 :             break_comma = true; /* while in declaration, newline should be
      74              :                                  * forced after comma */
      75            0 :             ps.p_stack[++ps.tos] = decl;
      76            0 :             ps.il[ps.tos] = ps.i_l_follow;
      77              : 
      78            0 :             if (ps.ljust_decl) {/* only do if we want left justified
      79              :                                  * declarations */
      80            0 :                 ps.ind_level = 0;
      81            0 :                 for (i = ps.tos - 1; i > 0; --i)
      82            0 :                     if (ps.p_stack[i] == decl)
      83            0 :                         ++ps.ind_level; /* indentation is number of
      84              :                                          * declaration levels deep we are */
      85            0 :                 ps.i_l_follow = ps.ind_level;
      86            0 :             }
      87            0 :         }
      88            0 :         break;
      89              : 
      90              :     case ifstmt:                /* scanned if (...) */
      91            0 :         if (ps.p_stack[ps.tos] == elsehead && ps.else_if)       /* "else if ..." */
      92              :                 /*
      93              :                  * Note that the stack pointer here is decremented, effectively
      94              :                  * reducing "else if" to "if". This saves a lot of stack space
      95              :                  * in case of a long "if-else-if ... else-if" sequence.
      96              :                  */
      97            0 :                 ps.i_l_follow = ps.il[ps.tos--];
      98              :         /* the rest is the same as for dolit and forstmt */
      99              :         /* FALLTHROUGH */
     100              :     case dolit:         /* 'do' */
     101              :     case forstmt:               /* for (...) */
     102            0 :         ps.p_stack[++ps.tos] = tk;
     103            0 :         ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
     104            0 :         ++ps.i_l_follow;        /* subsequent statements should be indented 1 */
     105            0 :         ps.search_brace = btype_2;
     106            0 :         break;
     107              : 
     108              :     case lbrace:                /* scanned { */
     109            0 :         break_comma = false;    /* don't break comma in an initial list */
     110            0 :         if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl
     111            0 :                 || ps.p_stack[ps.tos] == stmtl)
     112            0 :             ++ps.i_l_follow;    /* it is a random, isolated stmt group or a
     113              :                                  * declaration */
     114              :         else {
     115            0 :             if (s_code == e_code) {
     116              :                 /*
     117              :                  * only do this if there is nothing on the line
     118              :                  */
     119            0 :                 --ps.ind_level;
     120              :                 /*
     121              :                  * it is a group as part of a while, for, etc.
     122              :                  */
     123            0 :                 if (ps.p_stack[ps.tos] == swstmt && ps.case_indent >= 1)
     124            0 :                     --ps.ind_level;
     125              :                 /*
     126              :                  * for a switch, brace should be two levels out from the code
     127              :                  */
     128            0 :             }
     129              :         }
     130              : 
     131            0 :         ps.p_stack[++ps.tos] = lbrace;
     132            0 :         ps.il[ps.tos] = ps.ind_level;
     133            0 :         ps.p_stack[++ps.tos] = stmt;
     134              :         /* allow null stmt between braces */
     135            0 :         ps.il[ps.tos] = ps.i_l_follow;
     136            0 :         break;
     137              : 
     138              :     case whilestmt:             /* scanned while (...) */
     139            0 :         if (ps.p_stack[ps.tos] == dohead) {
     140              :             /* it is matched with do stmt */
     141            0 :             ps.ind_level = ps.i_l_follow = ps.il[ps.tos];
     142            0 :             ps.p_stack[++ps.tos] = whilestmt;
     143            0 :             ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
     144            0 :         }
     145              :         else {                  /* it is a while loop */
     146            0 :             ps.p_stack[++ps.tos] = whilestmt;
     147            0 :             ps.il[ps.tos] = ps.i_l_follow;
     148            0 :             ++ps.i_l_follow;
     149            0 :             ps.search_brace = btype_2;
     150              :         }
     151              : 
     152            0 :         break;
     153              : 
     154              :     case elselit:               /* scanned an else */
     155              : 
     156            0 :         if (ps.p_stack[ps.tos] != ifhead)
     157            0 :             diag2(1, "Unmatched 'else'");
     158              :         else {
     159            0 :             ps.ind_level = ps.il[ps.tos];       /* indentation for else should
     160              :                                                  * be same as for if */
     161            0 :             ps.i_l_follow = ps.ind_level + 1;   /* everything following should
     162              :                                                  * be in 1 level */
     163            0 :             ps.p_stack[ps.tos] = elsehead;
     164              :             /* remember if with else */
     165            0 :             ps.search_brace = btype_2 | ps.else_if;
     166              :         }
     167            0 :         break;
     168              : 
     169              :     case rbrace:                /* scanned a } */
     170              :         /* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */
     171            0 :         if (ps.tos > 0 && ps.p_stack[ps.tos - 1] == lbrace) {
     172            0 :             ps.ind_level = ps.i_l_follow = ps.il[--ps.tos];
     173            0 :             ps.p_stack[ps.tos] = stmt;
     174            0 :         }
     175              :         else
     176            0 :             diag2(1, "Statement nesting error");
     177            0 :         break;
     178              : 
     179              :     case swstmt:                /* had switch (...) */
     180            0 :         ps.p_stack[++ps.tos] = swstmt;
     181            0 :         ps.cstk[ps.tos] = case_ind;
     182              :         /* save current case indent level */
     183            0 :         ps.il[ps.tos] = ps.i_l_follow;
     184            0 :         case_ind = ps.i_l_follow + ps.case_indent;      /* cases should be one
     185              :                                                          * level down from
     186              :                                                          * switch */
     187            0 :         ps.i_l_follow += ps.case_indent + 1;    /* statements should be two
     188              :                                                  * levels in */
     189            0 :         ps.search_brace = btype_2;
     190            0 :         break;
     191              : 
     192              :     case semicolon:             /* this indicates a simple stmt */
     193            0 :         break_comma = false;    /* turn off flag to break after commas in a
     194              :                                  * declaration */
     195            0 :         ps.p_stack[++ps.tos] = stmt;
     196            0 :         ps.il[ps.tos] = ps.ind_level;
     197            0 :         break;
     198              : 
     199              :     default:                    /* this is an error */
     200            0 :         diag2(1, "Unknown code to parser");
     201            0 :         return;
     202              : 
     203              : 
     204              :     }                           /* end of switch */
     205              : 
     206            0 :     if (ps.tos >= nitems(ps.p_stack) - 1)
     207            0 :         errx(1, "Parser stack overflow");
     208              : 
     209            0 :     reduce();                   /* see if any reduction can be done */
     210              : 
     211              : #ifdef debug
     212              :     for (i = 1; i <= ps.tos; ++i)
     213              :         printf("(%d %d)", ps.p_stack[i], ps.il[i]);
     214              :     printf("\n");
     215              : #endif
     216              : 
     217            0 :     return;
     218            0 : }
     219              : 
     220              : /*
     221              :  * NAME: reduce
     222              :  *
     223              :  * FUNCTION: Implements the reduce part of the parsing algorithm
     224              :  *
     225              :  * ALGORITHM: The following reductions are done.  Reductions are repeated
     226              :  *      until no more are possible.
     227              :  *
     228              :  * Old TOS              New TOS
     229              :  * <stmt> <stmt>    <stmtl>
     230              :  * <stmtl> <stmt>   <stmtl>
     231              :  * do <stmt>              "dostmt"
     232              :  * if <stmt>              "ifstmt"
     233              :  * switch <stmt>  <stmt>
     234              :  * decl <stmt>            <stmt>
     235              :  * "ifelse" <stmt>      <stmt>
     236              :  * for <stmt>             <stmt>
     237              :  * while <stmt>           <stmt>
     238              :  * "dostmt" while     <stmt>
     239              :  *
     240              :  * On each reduction, ps.i_l_follow (the indentation for the following line)
     241              :  * is set to the indentation level associated with the old TOS.
     242              :  *
     243              :  * PARAMETERS: None
     244              :  *
     245              :  * RETURNS: Nothing
     246              :  *
     247              :  * GLOBALS: ps.cstk ps.i_l_follow = ps.il ps.p_stack = ps.tos =
     248              :  *
     249              :  * CALLS: None
     250              :  *
     251              :  * CALLED BY: parse
     252              :  *
     253              :  * HISTORY: initial coding      November 1976   D A Willcox of CAC
     254              :  *
     255              :  */
     256              : /*----------------------------------------------*\
     257              : |   REDUCTION PHASE                                 |
     258              : \*----------------------------------------------*/
     259              : static void
     260            0 : reduce(void)
     261              : {
     262            0 :     int i;
     263              : 
     264            0 :     for (;;) {                  /* keep looping until there is nothing left to
     265              :                                  * reduce */
     266              : 
     267            0 :         switch (ps.p_stack[ps.tos]) {
     268              : 
     269              :         case stmt:
     270            0 :             switch (ps.p_stack[ps.tos - 1]) {
     271              : 
     272              :             case stmt:
     273              :             case stmtl:
     274              :                 /* stmtl stmt or stmt stmt */
     275            0 :                 ps.p_stack[--ps.tos] = stmtl;
     276            0 :                 break;
     277              : 
     278              :             case dolit: /* <do> <stmt> */
     279            0 :                 ps.p_stack[--ps.tos] = dohead;
     280            0 :                 ps.i_l_follow = ps.il[ps.tos];
     281            0 :                 break;
     282              : 
     283              :             case ifstmt:
     284              :                 /* <if> <stmt> */
     285            0 :                 ps.p_stack[--ps.tos] = ifhead;
     286            0 :                 for (i = ps.tos - 1;
     287              :                         (
     288            0 :                          ps.p_stack[i] != stmt
     289            0 :                          &&
     290            0 :                          ps.p_stack[i] != stmtl
     291            0 :                          &&
     292            0 :                          ps.p_stack[i] != lbrace
     293              :                          );
     294            0 :                         --i);
     295            0 :                 ps.i_l_follow = ps.il[i];
     296              :                 /*
     297              :                  * for the time being, we will assume that there is no else on
     298              :                  * this if, and set the indentation level accordingly. If an
     299              :                  * else is scanned, it will be fixed up later
     300              :                  */
     301            0 :                 break;
     302              : 
     303              :             case swstmt:
     304              :                 /* <switch> <stmt> */
     305            0 :                 case_ind = ps.cstk[ps.tos - 1];
     306              :                 /* FALLTHROUGH */
     307              :             case decl:          /* finish of a declaration */
     308              :             case elsehead:
     309              :                 /* <<if> <stmt> else> <stmt> */
     310              :             case forstmt:
     311              :                 /* <for> <stmt> */
     312              :             case whilestmt:
     313              :                 /* <while> <stmt> */
     314            0 :                 ps.p_stack[--ps.tos] = stmt;
     315            0 :                 ps.i_l_follow = ps.il[ps.tos];
     316            0 :                 break;
     317              : 
     318              :             default:            /* <anything else> <stmt> */
     319            0 :                 return;
     320              : 
     321              :             }                   /* end of section for <stmt> on top of stack */
     322            0 :             break;
     323              : 
     324              :         case whilestmt: /* while (...) on top */
     325            0 :             if (ps.p_stack[ps.tos - 1] == dohead) {
     326              :                 /* it is termination of a do while */
     327            0 :                 ps.tos -= 2;
     328            0 :                 break;
     329              :             }
     330              :             else
     331            0 :                 return;
     332              : 
     333              :         default:                /* anything else on top */
     334            0 :             return;
     335              : 
     336              :         }
     337              :     }
     338            0 : }
        

Generated by: LCOV version 2.3.2-1