LCOV - code coverage report
Current view: top level - src/tools/pg_bsd_indent - indent.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 76.8 % 733 563
Test Date: 2026-02-27 17:14:52 Functions: 66.7 % 3 2
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-
       2              :  * Copyright (c) 1985 Sun Microsystems, Inc.
       3              :  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
       4              :  * Copyright (c) 1980, 1993
       5              :  *  The Regents of the University of California.  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[] = "@(#)indent.c   5.17 (Berkeley) 6/7/93";
      35              : #endif /* not lint */
      36              : #endif
      37              : 
      38              : #include "c.h"
      39              : 
      40              : #include <sys/param.h>
      41              : #include <err.h>
      42              : #include <fcntl.h>
      43              : #include <unistd.h>
      44              : #include <stdio.h>
      45              : #include <stdlib.h>
      46              : #include <string.h>
      47              : #include <ctype.h>
      48              : 
      49              : /* Tell indent_globs.h to define our global variables here */
      50              : #define DECLARE_INDENT_GLOBALS 1
      51              : 
      52              : #include "indent_globs.h"
      53              : #include "indent_codes.h"
      54              : #include "indent.h"
      55              : 
      56              : static void bakcopy(void);
      57              : static void indent_declaration(int cur_dec_ind, int tabs_to_var);
      58              : 
      59              : const char *in_name = "Standard Input";   /* will always point to name of input
      60              :                      * file */
      61              : const char *out_name = "Standard Output"; /* will always point to name
      62              :                          * of output file */
      63              : char        bakfile[MAXPGPATH] = "";
      64              : 
      65              : int
      66           19 : main(int argc, char **argv)
      67              : {
      68              :     int         dec_ind;    /* current indentation for declarations */
      69              :     int         di_stack[20];   /* a stack of structure indentation levels */
      70              :     int         force_nl;   /* when true, code must be broken */
      71           19 :     int         hd_type = 0;    /* used to store type of stmt for if (...),
      72              :                  * for (...), etc */
      73              :     int     i;      /* local loop counter */
      74              :     int         scase;      /* set to true when we see a case, so we will
      75              :                  * know what to do with the following colon */
      76              :     int         sp_sw;      /* when true, we are in the expression of
      77              :                  * if(...), while(...), etc. */
      78              :     int         squest;     /* when this is positive, we have seen a ?
      79              :                  * without the matching : in a <c>?<s>:<s>
      80              :                  * construct */
      81              :     const char *t_ptr;      /* used for copying tokens */
      82              :     int     tabs_to_var;    /* true if using tabs to indent to var name */
      83              :     int         type_code;  /* the type of token, returned by lexi */
      84              : 
      85           19 :     int         last_else = 0;  /* true iff last keyword was an else */
      86           19 :     const char *profile_name = NULL;
      87              :     struct parser_state transient_state; /* a copy for lookup */
      88              : 
      89              : 
      90              :     /*-----------------------------------------------*\
      91              :     |             INITIALIZATION              |
      92              :     \*-----------------------------------------------*/
      93              : 
      94           19 :     found_err = 0;
      95              : 
      96           19 :     ps.p_stack[0] = stmt;   /* this is the parser's stack */
      97           19 :     ps.last_nl = true;      /* this is true if the last thing scanned was
      98              :                  * a newline */
      99           19 :     ps.last_token = semicolon;
     100           19 :     combuf = (char *) malloc(bufsize);
     101           19 :     if (combuf == NULL)
     102            0 :     err(1, NULL);
     103           19 :     labbuf = (char *) malloc(bufsize);
     104           19 :     if (labbuf == NULL)
     105            0 :     err(1, NULL);
     106           19 :     codebuf = (char *) malloc(bufsize);
     107           19 :     if (codebuf == NULL)
     108            0 :     err(1, NULL);
     109           19 :     tokenbuf = (char *) malloc(bufsize);
     110           19 :     if (tokenbuf == NULL)
     111            0 :     err(1, NULL);
     112           19 :     alloc_typenames();
     113           19 :     l_com = combuf + bufsize - 5;
     114           19 :     l_lab = labbuf + bufsize - 5;
     115           19 :     l_code = codebuf + bufsize - 5;
     116           19 :     l_token = tokenbuf + bufsize - 5;
     117           19 :     combuf[0] = codebuf[0] = labbuf[0] = ' ';   /* set up code, label, and
     118              :                          * comment buffers */
     119           19 :     combuf[1] = codebuf[1] = labbuf[1] = '\0';
     120           19 :     ps.else_if = 1;     /* Default else-if special processing to on */
     121           19 :     s_lab = e_lab = labbuf + 1;
     122           19 :     s_code = e_code = codebuf + 1;
     123           19 :     s_com = e_com = combuf + 1;
     124           19 :     s_token = e_token = tokenbuf + 1;
     125              : 
     126           19 :     in_buffer = (char *) malloc(10);
     127           19 :     if (in_buffer == NULL)
     128            0 :     err(1, NULL);
     129           19 :     in_buffer_limit = in_buffer + 8;
     130           19 :     buf_ptr = buf_end = in_buffer;
     131           19 :     line_no = 1;
     132           19 :     had_eof = ps.in_decl = ps.decl_on_line = break_comma = false;
     133           19 :     sp_sw = force_nl = false;
     134           19 :     ps.in_or_st = false;
     135           19 :     ps.bl_line = true;
     136           19 :     dec_ind = 0;
     137           19 :     di_stack[ps.dec_nest = 0] = 0;
     138           19 :     ps.want_blank = ps.in_stmt = ps.ind_stmt = false;
     139              : 
     140           19 :     scase = ps.pcase = false;
     141           19 :     squest = 0;
     142           19 :     sc_end = NULL;
     143           19 :     bp_save = NULL;
     144           19 :     be_save = NULL;
     145              : 
     146           19 :     output = NULL;
     147           19 :     tabs_to_var = 0;
     148              : 
     149              :     /*--------------------------------------------------*\
     150              :     |           COMMAND LINE SCAN        |
     151              :     \*--------------------------------------------------*/
     152              : 
     153              : #ifdef undef
     154              :     max_col = 78;       /* -l78 */
     155              :     lineup_to_parens = 1;   /* -lp */
     156              :     lineup_to_parens_always = 0;    /* -nlpl */
     157              :     ps.ljust_decl = 0;      /* -ndj */
     158              :     ps.com_ind = 33;        /* -c33 */
     159              :     star_comment_cont = 1;  /* -sc */
     160              :     ps.ind_size = 8;        /* -i8 */
     161              :     verbose = 0;
     162              :     ps.decl_indent = 16;    /* -di16 */
     163              :     ps.local_decl_indent = -1;  /* if this is not set to some nonnegative value
     164              :                  * by an arg, we will set this equal to
     165              :                  * ps.decl_ind */
     166              :     ps.indent_parameters = 1;   /* -ip */
     167              :     ps.decl_com_ind = 0;    /* if this is not set to some positive value
     168              :                  * by an arg, we will set this equal to
     169              :                  * ps.com_ind */
     170              :     btype_2 = 1;        /* -br */
     171              :     cuddle_else = 1;        /* -ce */
     172              :     ps.unindent_displace = 0;   /* -d0 */
     173              :     ps.case_indent = 0;     /* -cli0 */
     174              :     format_block_comments = 1;  /* -fcb */
     175              :     format_col1_comments = 1;   /* -fc1 */
     176              :     procnames_start_line = 1;   /* -psl */
     177              :     proc_calls_space = 0;   /* -npcs */
     178              :     comment_delimiter_on_blankline = 1; /* -cdb */
     179              :     ps.leave_comma = 1;     /* -nbc */
     180              : #endif
     181              : 
     182           74 :     for (i = 1; i < argc; ++i)
     183           55 :     if (strcmp(argv[i], "-npro") == 0)
     184            0 :         break;
     185           55 :     else if (argv[i][0] == '-' && argv[i][1] == 'P' && argv[i][2] != '\0')
     186           18 :         profile_name = argv[i]; /* non-empty -P (set profile) */
     187           19 :     set_defaults();
     188           19 :     if (i >= argc)
     189           19 :     set_profile(profile_name);
     190              : 
     191           73 :     for (i = 1; i < argc; ++i) {
     192              : 
     193              :     /*
     194              :      * look thru args (if any) for changes to defaults
     195              :      */
     196           55 :     if (argv[i][0] != '-') {/* no flag on parameter */
     197           36 :         if (input == NULL) {    /* we must have the input file */
     198           18 :         in_name = argv[i];  /* remember name of input file */
     199           18 :         input = fopen(in_name, "r");
     200           18 :         if (input == NULL)  /* check for open error */
     201            0 :             err(1, "%s", in_name);
     202           18 :         continue;
     203              :         }
     204           18 :         else if (output == NULL) {  /* we have the output file */
     205           18 :         out_name = argv[i]; /* remember name of output file */
     206           18 :         if (strcmp(in_name, out_name) == 0) {   /* attempt to overwrite
     207              :                              * the file */
     208            0 :             errx(1, "input and output files must be different");
     209              :         }
     210           18 :         output = fopen(out_name, "wb");
     211           18 :         if (output == NULL) /* check for create error */
     212            0 :             err(1, "%s", out_name);
     213           18 :         continue;
     214              :         }
     215            0 :         errx(1, "unknown parameter: %s", argv[i]);
     216              :     }
     217              :     else
     218           19 :         set_option(argv[i]);
     219              :     }               /* end of for */
     220           18 :     if (input == NULL)
     221            0 :     input = stdin;
     222           18 :     if (output == NULL) {
     223            0 :     if (input == stdin)
     224            0 :         output = stdout;
     225              :     else {
     226            0 :         out_name = in_name;
     227            0 :         bakcopy();
     228              :     }
     229              :     }
     230              : 
     231           18 :     if (ps.com_ind <= 1)
     232            0 :     ps.com_ind = 2;     /* dont put normal comments before column 2 */
     233           18 :     if (block_comment_max_col <= 0)
     234           18 :     block_comment_max_col = max_col;
     235           18 :     if (ps.local_decl_indent < 0)    /* if not specified by user, set this */
     236           18 :     ps.local_decl_indent = ps.decl_indent;
     237           18 :     if (ps.decl_com_ind <= 0)    /* if not specified by user, set this */
     238           18 :     ps.decl_com_ind = ps.ljust_decl ? (ps.com_ind <= 10 ? 2 : ps.com_ind - 8) : ps.com_ind;
     239           18 :     if (continuation_indent == 0)
     240           18 :     continuation_indent = ps.ind_size;
     241           18 :     fill_buffer();      /* get first batch of stuff into input buffer */
     242              : 
     243           18 :     parse(semicolon);
     244              :     {
     245           18 :     char *p = buf_ptr;
     246           18 :     int col = 1;
     247              : 
     248              :     while (1) {
     249           18 :         if (*p == ' ')
     250            0 :         col++;
     251           18 :         else if (*p == '\t')
     252            0 :         col = tabsize * (1 + (col - 1) / tabsize) + 1;
     253              :         else
     254           18 :         break;
     255            0 :         p++;
     256              :     }
     257           18 :     if (col > ps.ind_size)
     258            0 :         ps.ind_level = ps.i_l_follow = col / ps.ind_size;
     259              :     }
     260              : 
     261              :     /*
     262              :      * START OF MAIN LOOP
     263              :      */
     264              : 
     265         1214 :     while (1) {         /* this is the main loop.  it will go until we
     266              :                  * reach eof */
     267         1232 :     int comment_buffered = false;
     268              : 
     269         1232 :     type_code = lexi(&ps);  /* lexi reads one token.  The actual
     270              :                  * characters read are stored in "token". lexi
     271              :                  * returns a code indicating the type of token */
     272              : 
     273              :     /*
     274              :      * The following code moves newlines and comments following an if (),
     275              :      * while (), else, etc. up to the start of the following stmt to
     276              :      * a buffer. This allows proper handling of both kinds of brace
     277              :      * placement (-br, -bl) and cuddling "else" (-ce).
     278              :      */
     279              : 
     280         1321 :     while (ps.search_brace) {
     281          216 :         switch (type_code) {
     282           46 :         case newline:
     283           46 :         if (sc_end == NULL) {
     284           30 :             save_com = sc_buf;
     285           30 :             save_com[0] = save_com[1] = ' ';
     286           30 :             sc_end = &save_com[2];
     287              :         }
     288           46 :         *sc_end++ = '\n';
     289              :         /*
     290              :          * We may have inherited a force_nl == true from the previous
     291              :          * token (like a semicolon). But once we know that a newline
     292              :          * has been scanned in this loop, force_nl should be false.
     293              :          *
     294              :          * However, the force_nl == true must be preserved if newline
     295              :          * is never scanned in this loop, so this assignment cannot be
     296              :          * done earlier.
     297              :          */
     298           46 :         force_nl = false;
     299           46 :         break;
     300            0 :         case form_feed:
     301            0 :         break;
     302            9 :         case comment:
     303            9 :         if (sc_end == NULL) {
     304              :             /*
     305              :              * Copy everything from the start of the line, because
     306              :              * pr_comment() will use that to calculate original
     307              :              * indentation of a boxed comment.
     308              :              */
     309            4 :             memcpy(sc_buf, in_buffer, buf_ptr - in_buffer - 4);
     310            4 :             save_com = sc_buf + (buf_ptr - in_buffer - 4);
     311            4 :             save_com[0] = save_com[1] = ' ';
     312            4 :             sc_end = &save_com[2];
     313              :         }
     314            9 :         comment_buffered = true;
     315            9 :         *sc_end++ = '/';    /* copy in start of comment */
     316            9 :         *sc_end++ = '*';
     317              :         for (;;) {  /* loop until we get to the end of the comment */
     318          293 :             *sc_end = *buf_ptr++;
     319          293 :             if (buf_ptr >= buf_end)
     320            4 :             fill_buffer();
     321          293 :             if (*sc_end++ == '*' && *buf_ptr == '/')
     322            9 :             break;  /* we are at end of comment */
     323          284 :             if (sc_end >= &save_com[sc_size]) {  /* check for temp buffer
     324              :                              * overflow */
     325            0 :             diag2(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever");
     326            0 :             fflush(output);
     327            0 :             exit(1);
     328              :             }
     329              :         }
     330            9 :         *sc_end++ = '/';    /* add ending slash */
     331            9 :         if (++buf_ptr >= buf_end)    /* get past / in buffer */
     332            0 :             fill_buffer();
     333            9 :         break;
     334           29 :         case lbrace:
     335              :         /*
     336              :          * Put KNF-style lbraces before the buffered up tokens and
     337              :          * jump out of this loop in order to avoid copying the token
     338              :          * again under the default case of the switch below.
     339              :          */
     340           29 :         if (sc_end != NULL && btype_2) {
     341           15 :             save_com[0] = '{';
     342              :             /*
     343              :              * Originally the lbrace may have been alone on its own
     344              :              * line, but it will be moved into "the else's line", so
     345              :              * if there was a newline resulting from the "{" before,
     346              :              * it must be scanned now and ignored.
     347              :              */
     348           39 :             while (isspace((unsigned char)*buf_ptr)) {
     349           28 :             if (++buf_ptr >= buf_end)
     350           14 :                 fill_buffer();
     351           28 :             if (*buf_ptr == '\n')
     352            4 :                 break;
     353              :             }
     354           15 :             goto sw_buffer;
     355              :         }
     356              :         pg_fallthrough;
     357              :         default:        /* it is the start of a normal statement */
     358              :         {
     359              :             int remove_newlines;
     360              : 
     361          146 :             remove_newlines =
     362              :             /* "} else" */
     363            2 :             (type_code == sp_nparen && *token == 'e' &&
     364            2 :                 e_code != s_code && e_code[-1] == '}')
     365              :             /* "else if" */
     366          149 :             || (type_code == sp_paren && *token == 'i' &&
     367            1 :                 last_else && ps.else_if);
     368          146 :             if (remove_newlines)
     369            3 :             force_nl = false;
     370          146 :             if (sc_end == NULL) {   /* ignore buffering if
     371              :                          * comment wasn't saved up */
     372          127 :             ps.search_brace = false;
     373          127 :             goto check_type;
     374              :             }
     375           38 :             while (sc_end > save_com && isblank((unsigned char)sc_end[-1])) {
     376           19 :             sc_end--;
     377              :             }
     378           19 :             if (swallow_optional_blanklines ||
     379           13 :             (!comment_buffered && remove_newlines)) {
     380            1 :             force_nl = !remove_newlines;
     381            4 :             while (sc_end > save_com && sc_end[-1] == '\n') {
     382            3 :                 sc_end--;
     383              :             }
     384              :             }
     385           19 :             if (force_nl) { /* if we should insert a nl here, put
     386              :                      * it into the buffer */
     387            1 :             force_nl = false;
     388            1 :             --line_no;  /* this will be re-increased when the
     389              :                      * newline is read from the buffer */
     390            1 :             *sc_end++ = '\n';
     391            1 :             *sc_end++ = ' ';
     392            1 :             if (verbose)    /* print error msg if the line was
     393              :                      * not already broken */
     394            0 :                 diag2(0, "Line broken");
     395              :             }
     396           86 :             for (t_ptr = token; *t_ptr; ++t_ptr)
     397           67 :             *sc_end++ = *t_ptr;
     398              : 
     399           19 :         sw_buffer:
     400           34 :             ps.search_brace = false;    /* stop looking for start of
     401              :                          * stmt */
     402           34 :             bp_save = buf_ptr;  /* save current input buffer */
     403           34 :             be_save = buf_end;
     404           34 :             buf_ptr = save_com; /* fix so that subsequent calls to
     405              :                      * lexi will take tokens out of
     406              :                      * save_com */
     407           34 :             *sc_end++ = ' ';/* add trailing blank, just in case */
     408           34 :             buf_end = sc_end;
     409           34 :             sc_end = NULL;
     410           34 :             break;
     411              :         }
     412              :         }           /* end of switch */
     413              :         /*
     414              :          * We must make this check, just in case there was an unexpected
     415              :          * EOF.
     416              :          */
     417           89 :         if (type_code != 0) {
     418              :         /*
     419              :          * The only intended purpose of calling lexi() below is to
     420              :          * categorize the next token in order to decide whether to
     421              :          * continue buffering forthcoming tokens. Once the buffering
     422              :          * is over, lexi() will be called again elsewhere on all of
     423              :          * the tokens - this time for normal processing.
     424              :          *
     425              :          * Calling it for this purpose is a bug, because lexi() also
     426              :          * changes the parser state and discards leading whitespace,
     427              :          * which is needed mostly for comment-related considerations.
     428              :          *
     429              :          * Work around the former problem by giving lexi() a copy of
     430              :          * the current parser state and discard it if the call turned
     431              :          * out to be just a look ahead.
     432              :          *
     433              :          * Work around the latter problem by copying all whitespace
     434              :          * characters into the buffer so that the later lexi() call
     435              :          * will read them.
     436              :          */
     437           89 :         if (sc_end != NULL) {
     438           86 :             while (*buf_ptr == ' ' || *buf_ptr == '\t') {
     439           31 :             *sc_end++ = *buf_ptr++;
     440           31 :             if (sc_end >= &save_com[sc_size]) {
     441            0 :                 errx(1, "input too long");
     442              :             }
     443              :             }
     444           55 :             if (buf_ptr >= buf_end) {
     445            0 :             fill_buffer();
     446              :             }
     447              :         }
     448           89 :         transient_state = ps;
     449           89 :         type_code = lexi(&transient_state); /* read another token */
     450           89 :         if (type_code != newline && type_code != form_feed &&
     451           50 :             type_code != comment && !transient_state.search_brace) {
     452           16 :             ps = transient_state;
     453              :         }
     454              :         }
     455              :     }           /* end of while (search_brace) */
     456         1105 :     last_else = 0;
     457         1232 : check_type:
     458         1232 :     if (type_code == 0) {   /* we got eof */
     459           18 :         if (s_lab != e_lab || s_code != e_code
     460            1 :             || s_com != e_com)  /* must dump end of line */
     461           17 :         dump_line();
     462           18 :         if (ps.tos > 1)  /* check for balanced braces */
     463            0 :         diag2(1, "Stuff missing from end of file");
     464              : 
     465           18 :         if (verbose) {
     466            0 :         printf("There were %d output lines and %d comments\n",
     467              :                ps.out_lines, ps.out_coms);
     468            0 :         printf("(Lines with comments)/(Lines with code): %6.3f\n",
     469              :                (1.0 * ps.com_lines) / code_lines);
     470              :         }
     471           18 :         fflush(output);
     472           18 :         exit(found_err);
     473              :     }
     474         1214 :     if (
     475         1156 :         (type_code != comment) &&
     476          877 :         (type_code != newline) &&
     477          866 :         (type_code != preesc) &&
     478              :         (type_code != form_feed)) {
     479          866 :         if (force_nl &&
     480            7 :             (type_code != semicolon) &&
     481            4 :             (type_code != lbrace || !btype_2)) {
     482              :         /* we should force a broken line here */
     483            6 :         if (verbose)
     484            0 :             diag2(0, "Line broken");
     485            6 :         dump_line();
     486            6 :         ps.want_blank = false;  /* dont insert blank at line start */
     487            6 :         force_nl = false;
     488              :         }
     489          866 :         ps.in_stmt = true;  /* turn on flag which causes an extra level of
     490              :                  * indentation. this is turned off by a ; or
     491              :                  * '}' */
     492          866 :         if (s_com != e_com) {   /* the turkey has embedded a comment
     493              :                      * in a line. fix it */
     494            2 :         int len = e_com - s_com;
     495              : 
     496            2 :         CHECK_SIZE_CODE(len + 3);
     497            2 :         *e_code++ = ' ';
     498            2 :         memcpy(e_code, s_com, len);
     499            2 :         e_code += len;
     500            2 :         *e_code++ = ' ';
     501            2 :         *e_code = '\0'; /* null terminate code sect */
     502            2 :         ps.want_blank = false;
     503            2 :         e_com = s_com;
     504              :         }
     505              :     }
     506          348 :     else if (type_code != comment)  /* preserve force_nl thru a comment */
     507          290 :         force_nl = false;   /* cancel forced newline after newline, form
     508              :                  * feed, etc */
     509              : 
     510              : 
     511              : 
     512              :     /*-----------------------------------------------------*\
     513              :     |      do switch on type of token scanned       |
     514              :     \*-----------------------------------------------------*/
     515         1214 :     CHECK_SIZE_CODE(3); /* maximum number of increments of e_code
     516              :                  * before the next CHECK_SIZE_CODE or
     517              :                  * dump_line() is 2. After that there's the
     518              :                  * final increment for the null character. */
     519         1214 :     switch (type_code) {    /* now, decide what to do with the token */
     520              : 
     521            0 :     case form_feed: /* found a form feed in line */
     522            0 :         ps.use_ff = true;   /* a form feed is treated much like a newline */
     523            0 :         dump_line();
     524            0 :         ps.want_blank = false;
     525            0 :         break;
     526              : 
     527          279 :     case newline:
     528          279 :         if (ps.last_token != comma || ps.p_l_follow > 0
     529           16 :             || !ps.leave_comma || ps.block_init || !break_comma || s_com != e_com) {
     530          271 :         dump_line();
     531          271 :         ps.want_blank = false;
     532              :         }
     533          279 :         ++line_no;      /* keep track of input line number */
     534          279 :         break;
     535              : 
     536           78 :     case lparen:        /* got a '(' or '[' */
     537              :         /* count parens to make Healy happy */
     538           78 :         if (++ps.p_l_follow == nitems(ps.paren_indents)) {
     539            0 :         diag3(0, "Reached internal limit of %d unclosed parens",
     540              :             nitems(ps.paren_indents));
     541            0 :         ps.p_l_follow--;
     542              :         }
     543           78 :         if (*token == '[')
     544              :         /* not a function pointer declaration or a function call */;
     545           71 :         else if (ps.in_decl && !ps.block_init && !ps.dumped_decl_indent &&
     546            4 :         ps.procname[0] == '\0' && ps.paren_level == 0) {
     547              :         /* function pointer declarations */
     548            4 :         indent_declaration(dec_ind, tabs_to_var);
     549            4 :         ps.dumped_decl_indent = true;
     550              :         }
     551           67 :         else if (ps.want_blank &&
     552           43 :             ((ps.last_token != ident && ps.last_token != funcname) ||
     553              :             /* offsetof (1) is never allowed a space; sizeof (2) gets
     554              :              * one iff -bs; all other keywords (>2) always get a space
     555              :              * before lparen */
     556           17 :             ps.keyword + Bill_Shannon > 2))
     557           27 :         *e_code++ = ' ';
     558           78 :         ps.want_blank = false;
     559           78 :         *e_code++ = token[0];
     560           78 :         ps.paren_indents[ps.p_l_follow - 1] = count_spaces_until(1, s_code, e_code) - 1;
     561           78 :         if (sp_sw && ps.p_l_follow == 1 && extra_expression_indent
     562            0 :             && ps.paren_indents[0] < 2 * ps.ind_size)
     563            0 :         ps.paren_indents[0] = 2 * ps.ind_size;
     564           78 :         if (ps.in_or_st && *token == '(' && ps.tos <= 2) {
     565              :         /*
     566              :          * this is a kluge to make sure that declarations will be
     567              :          * aligned right if proc decl has an explicit type on it, i.e.
     568              :          * "int a(x) {..."
     569              :          */
     570           27 :         parse(semicolon);   /* I said this was a kluge... */
     571           27 :         ps.in_or_st = false;    /* turn off flag for structure decl or
     572              :                      * initialization */
     573              :         }
     574              :         /*
     575              :          * parenthesized type following sizeof or offsetof is not a cast,
     576              :          * and we assume the same for any other non-keyword identifier,
     577              :          * to support macros that take types
     578              :          */
     579           78 :         if (ps.last_token == ident &&
     580           24 :         (ps.keyword == 0 || ps.keyword == 1 || ps.keyword == 2))
     581           23 :         ps.not_cast_mask |= 1 << ps.p_l_follow;
     582           78 :         break;
     583              : 
     584           78 :     case rparen:        /* got a ')' or ']' */
     585           78 :         if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.not_cast_mask) {
     586           31 :         ps.last_u_d = true;
     587           31 :         ps.cast_mask &= (1 << ps.p_l_follow) - 1;
     588           31 :         ps.want_blank = space_after_cast;
     589              :         } else
     590           47 :         ps.want_blank = true;
     591           78 :         ps.not_cast_mask &= (1 << ps.p_l_follow) - 1;
     592           78 :         if (--ps.p_l_follow < 0) {
     593            0 :         ps.p_l_follow = 0;
     594            0 :         diag3(0, "Extra %c", *token);
     595              :         }
     596           78 :         if (e_code == s_code)   /* if the paren starts the line */
     597            0 :         ps.paren_level = ps.p_l_follow; /* then indent it */
     598              : 
     599           78 :         *e_code++ = token[0];
     600              : 
     601           78 :         if (sp_sw && (ps.p_l_follow == 0)) {    /* check for end of if
     602              :                              * (...), or some such */
     603           11 :         sp_sw = false;
     604           11 :         force_nl = true;/* must force newline after if */
     605           11 :         ps.last_u_d = true; /* inform lexi that a following
     606              :                      * operator is unary */
     607           11 :         ps.in_stmt = false; /* dont use stmt continuation
     608              :                      * indentation */
     609              : 
     610           11 :         parse(hd_type); /* let parser worry about if, or whatever */
     611              :         }
     612           78 :         ps.search_brace = btype_2;  /* this should ensure that constructs
     613              :                      * such as main(){...} and int[]{...}
     614              :                      * have their braces put in the right
     615              :                      * place */
     616           78 :         break;
     617              : 
     618           42 :     case unary_op:      /* this could be any unary operation */
     619           42 :         if (!ps.dumped_decl_indent && ps.in_decl && !ps.block_init &&
     620           15 :         ps.procname[0] == '\0' && ps.paren_level == 0) {
     621              :         /* pointer declarations */
     622              : 
     623              :         /*
     624              :          * if this is a unary op in a declaration, we should indent
     625              :          * this token
     626              :          */
     627           27 :         for (i = 0; token[i]; ++i)
     628              :             /* find length of token */;
     629           12 :         indent_declaration(dec_ind - i, tabs_to_var);
     630           12 :         ps.dumped_decl_indent = true;
     631              :         }
     632           30 :         else if (ps.want_blank)
     633           19 :         *e_code++ = ' ';
     634              : 
     635              :         {
     636           42 :         int len = e_token - s_token;
     637              : 
     638           42 :         CHECK_SIZE_CODE(len);
     639           42 :         memcpy(e_code, token, len);
     640           42 :         e_code += len;
     641              :         }
     642           42 :         ps.want_blank = false;
     643           42 :         break;
     644              : 
     645           39 :     case binary_op: /* any binary operation */
     646              :         {
     647           39 :         int len = e_token - s_token;
     648              : 
     649           39 :         CHECK_SIZE_CODE(len + 1);
     650           39 :         if (ps.want_blank)
     651           39 :             *e_code++ = ' ';
     652           39 :         memcpy(e_code, token, len);
     653           39 :         e_code += len;
     654              :         }
     655           39 :         ps.want_blank = true;
     656           39 :         break;
     657              : 
     658            0 :     case postop:        /* got a trailing ++ or -- */
     659            0 :         *e_code++ = token[0];
     660            0 :         *e_code++ = token[1];
     661            0 :         ps.want_blank = true;
     662            0 :         break;
     663              : 
     664            0 :     case question:      /* got a ? */
     665            0 :         squest++;       /* this will be used when a later colon
     666              :                  * appears so we can distinguish the
     667              :                  * <c>?<n>:<n> construct */
     668            0 :         if (ps.want_blank)
     669            0 :         *e_code++ = ' ';
     670            0 :         *e_code++ = '?';
     671            0 :         ps.want_blank = true;
     672            0 :         break;
     673              : 
     674            2 :     case casestmt:      /* got word 'case' or 'default' */
     675            2 :         scase = true;   /* so we can process the later colon properly */
     676            2 :         goto copy_id;
     677              : 
     678            5 :     case colon:     /* got a ':' */
     679            5 :         if (squest > 0) {    /* it is part of the <c>?<n>: <n> construct */
     680            0 :         --squest;
     681            0 :         if (ps.want_blank)
     682            0 :             *e_code++ = ' ';
     683            0 :         *e_code++ = ':';
     684            0 :         ps.want_blank = true;
     685            0 :         break;
     686              :         }
     687            5 :         if (ps.in_or_st) {
     688            0 :         *e_code++ = ':';
     689            0 :         ps.want_blank = false;
     690            0 :         break;
     691              :         }
     692            5 :         ps.in_stmt = false; /* seeing a label does not imply we are in a
     693              :                  * stmt */
     694              :         /*
     695              :          * turn everything so far into a label
     696              :          */
     697              :         {
     698            5 :         int len = e_code - s_code;
     699              : 
     700            5 :         CHECK_SIZE_LAB(len + 3);
     701            5 :         memcpy(e_lab, s_code, len);
     702            5 :         e_lab += len;
     703            5 :         *e_lab++ = ':';
     704            5 :         *e_lab = '\0';
     705            5 :         e_code = s_code;
     706              :         }
     707            5 :         force_nl = ps.pcase = scase;    /* ps.pcase will be used by
     708              :                          * dump_line to decide how to
     709              :                          * indent the label. force_nl
     710              :                          * will force a case n: to be
     711              :                          * on a line by itself */
     712            5 :         scase = false;
     713            5 :         ps.want_blank = false;
     714            5 :         break;
     715              : 
     716           73 :     case semicolon: /* got a ';' */
     717           73 :         if (ps.dec_nest == 0)
     718           67 :         ps.in_or_st = false;/* we are not in an initialization or
     719              :                      * structure declaration */
     720           73 :         scase = false;  /* these will only need resetting in an error */
     721           73 :         squest = 0;
     722           73 :         if (ps.last_token == rparen)
     723           13 :         ps.in_parameter_declaration = 0;
     724           73 :         ps.cast_mask = 0;
     725           73 :         ps.not_cast_mask = 0;
     726           73 :         ps.block_init = 0;
     727           73 :         ps.block_init_level = 0;
     728           73 :         ps.just_saw_decl--;
     729              : 
     730           73 :         if (ps.in_decl && s_code == e_code && !ps.block_init &&
     731            1 :         !ps.dumped_decl_indent && ps.paren_level == 0) {
     732              :         /* indent stray semicolons in declarations */
     733            1 :         indent_declaration(dec_ind - 1, tabs_to_var);
     734            1 :         ps.dumped_decl_indent = true;
     735              :         }
     736              : 
     737           73 :         ps.in_decl = (ps.dec_nest > 0);  /* if we were in a first level
     738              :                          * structure declaration, we
     739              :                          * arent any more */
     740              : 
     741           73 :         if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) {
     742              : 
     743              :         /*
     744              :          * This should be true iff there were unbalanced parens in the
     745              :          * stmt.  It is a bit complicated, because the semicolon might
     746              :          * be in a for stmt
     747              :          */
     748            0 :         diag2(1, "Unbalanced parens");
     749            0 :         ps.p_l_follow = 0;
     750            0 :         if (sp_sw) {    /* this is a check for an if, while, etc. with
     751              :                  * unbalanced parens */
     752            0 :             sp_sw = false;
     753            0 :             parse(hd_type); /* dont lose the if, or whatever */
     754              :         }
     755              :         }
     756           73 :         *e_code++ = ';';
     757           73 :         ps.want_blank = true;
     758           73 :         ps.in_stmt = (ps.p_l_follow > 0);    /* we are no longer in the
     759              :                          * middle of a stmt */
     760              : 
     761           73 :         if (!sp_sw) {   /* if not if for (;;) */
     762           73 :         parse(semicolon);   /* let parser know about end of stmt */
     763           73 :         force_nl = true;/* force newline after an end of stmt */
     764              :         }
     765           73 :         break;
     766              : 
     767           41 :     case lbrace:        /* got a '{' */
     768           41 :         ps.in_stmt = false; /* dont indent the {} */
     769           41 :         if (!ps.block_init)
     770           33 :         force_nl = true;/* force other stuff on same line as '{' onto
     771              :                  * new line */
     772            8 :         else if (ps.block_init_level <= 0)
     773            5 :         ps.block_init_level = 1;
     774              :         else
     775            3 :         ps.block_init_level++;
     776              : 
     777           41 :         if (s_code != e_code && !ps.block_init) {
     778           29 :         if (!btype_2) {
     779            1 :             dump_line();
     780            1 :             ps.want_blank = false;
     781              :         }
     782           28 :         else if (ps.in_parameter_declaration && !ps.in_or_st) {
     783           20 :             ps.i_l_follow = 0;
     784           20 :             if (function_brace_split) { /* dump the line prior to the
     785              :                          * brace ... */
     786           20 :             dump_line();
     787           20 :             ps.want_blank = false;
     788              :             } else  /* add a space between the decl and brace */
     789            0 :             ps.want_blank = true;
     790              :         }
     791              :         }
     792           41 :         if (ps.in_parameter_declaration)
     793           21 :         prefix_blankline_requested = 0;
     794              : 
     795           41 :         if (ps.p_l_follow > 0) { /* check for preceding unbalanced
     796              :                      * parens */
     797            0 :         diag2(1, "Unbalanced parens");
     798            0 :         ps.p_l_follow = 0;
     799            0 :         if (sp_sw) {    /* check for unclosed if, for, etc. */
     800            0 :             sp_sw = false;
     801            0 :             parse(hd_type);
     802            0 :             ps.ind_level = ps.i_l_follow;
     803              :         }
     804              :         }
     805           41 :         if (s_code == e_code)
     806           29 :         ps.ind_stmt = false;    /* dont put extra indentation on line
     807              :                      * with '{' */
     808           41 :         if (ps.in_decl && ps.in_or_st) {    /* this is either a structure
     809              :                          * declaration or an init */
     810           13 :         di_stack[ps.dec_nest] = dec_ind;
     811           13 :         if (++ps.dec_nest == nitems(di_stack)) {
     812            0 :             diag3(0, "Reached internal limit of %d struct levels",
     813              :             nitems(di_stack));
     814            0 :             ps.dec_nest--;
     815              :         }
     816              :         /* ?        dec_ind = 0; */
     817              :         }
     818              :         else {
     819           28 :         ps.decl_on_line = false;    /* we can't be in the middle of
     820              :                          * a declaration, so don't do
     821              :                          * special indentation of
     822              :                          * comments */
     823           28 :         if (blanklines_after_declarations_at_proctop
     824            0 :             && ps.in_parameter_declaration)
     825            0 :             postfix_blankline_requested = 1;
     826           28 :         ps.in_parameter_declaration = 0;
     827           28 :         ps.in_decl = false;
     828              :         }
     829           41 :         dec_ind = 0;
     830           41 :         parse(lbrace);  /* let parser know about this */
     831           41 :         if (ps.want_blank)  /* put a blank before '{' if '{' is not at
     832              :                  * start of line */
     833           12 :         *e_code++ = ' ';
     834           41 :         ps.want_blank = false;
     835           41 :         *e_code++ = '{';
     836           41 :         ps.just_saw_decl = 0;
     837           41 :         break;
     838              : 
     839           41 :     case rbrace:        /* got a '}' */
     840           41 :         if (ps.p_stack[ps.tos] == decl && !ps.block_init)   /* semicolons can be
     841              :                                  * omitted in
     842              :                                  * declarations */
     843            0 :         parse(semicolon);
     844           41 :         if (ps.p_l_follow) {/* check for unclosed if, for, else. */
     845            0 :         diag2(1, "Unbalanced parens");
     846            0 :         ps.p_l_follow = 0;
     847            0 :         sp_sw = false;
     848              :         }
     849           41 :         ps.just_saw_decl = 0;
     850           41 :         ps.block_init_level--;
     851           41 :         if (s_code != e_code && !ps.block_init) {   /* '}' must be first on
     852              :                              * line */
     853            0 :         if (verbose)
     854            0 :             diag2(0, "Line broken");
     855            0 :         dump_line();
     856              :         }
     857           41 :         *e_code++ = '}';
     858           41 :         ps.want_blank = true;
     859           41 :         ps.in_stmt = ps.ind_stmt = false;
     860           41 :         if (ps.dec_nest > 0) {   /* we are in multi-level structure
     861              :                      * declaration */
     862           13 :         dec_ind = di_stack[--ps.dec_nest];
     863           13 :         if (ps.dec_nest == 0 && !ps.in_parameter_declaration)
     864           10 :             ps.just_saw_decl = 2;
     865           13 :         ps.in_decl = true;
     866              :         }
     867           41 :         prefix_blankline_requested = 0;
     868           41 :         parse(rbrace);  /* let parser know about this */
     869           41 :         ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead
     870           82 :         && ps.il[ps.tos] >= ps.ind_level;
     871           41 :         if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0)
     872            0 :         postfix_blankline_requested = 1;
     873           41 :         break;
     874              : 
     875            1 :     case swstmt:        /* got keyword "switch" */
     876            1 :         sp_sw = true;
     877            1 :         hd_type = swstmt;   /* keep this for when we have seen the
     878              :                  * expression */
     879            1 :         goto copy_id;   /* go move the token into buffer */
     880              : 
     881           10 :     case sp_paren:      /* token is if, while, for */
     882           10 :         sp_sw = true;   /* the interesting stuff is done after the
     883              :                  * expression is scanned */
     884           10 :         hd_type = (*token == 'i' ? ifstmt :
     885            0 :                (*token == 'w' ? whilestmt : forstmt));
     886              : 
     887              :         /*
     888              :          * remember the type of header for later use by parser
     889              :          */
     890           10 :         goto copy_id;   /* copy the token into line */
     891              : 
     892            5 :     case sp_nparen: /* got else, do */
     893            5 :         ps.in_stmt = false;
     894            5 :         if (*token == 'e') {
     895            5 :         if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) {
     896            0 :             if (verbose)
     897            0 :             diag2(0, "Line broken");
     898            0 :             dump_line();/* make sure this starts a line */
     899            0 :             ps.want_blank = false;
     900              :         }
     901            5 :         force_nl = true;/* also, following stuff must go onto new line */
     902            5 :         last_else = 1;
     903            5 :         parse(elselit);
     904              :         }
     905              :         else {
     906            0 :         if (e_code != s_code) { /* make sure this starts a line */
     907            0 :             if (verbose)
     908            0 :             diag2(0, "Line broken");
     909            0 :             dump_line();
     910            0 :             ps.want_blank = false;
     911              :         }
     912            0 :         force_nl = true;/* also, following stuff must go onto new line */
     913            0 :         last_else = 0;
     914            0 :         parse(dolit);
     915              :         }
     916            5 :         goto copy_id;   /* move the token into line */
     917              : 
     918           15 :     case type_def:
     919              :     case storage:
     920           15 :         prefix_blankline_requested = 0;
     921           15 :         goto copy_id;
     922              : 
     923           18 :     case structure:
     924           18 :         if (ps.p_l_follow > 0)
     925           10 :         goto copy_id;
     926              :         pg_fallthrough;
     927              :     case decl:      /* we have a declaration type (int, etc.) */
     928           87 :         parse(decl);    /* let parser worry about indentation */
     929           87 :         if (ps.last_token == rparen && ps.tos <= 1) {
     930            1 :         if (s_code != e_code) {
     931            0 :             dump_line();
     932            0 :             ps.want_blank = 0;
     933              :         }
     934              :         }
     935           87 :         if (ps.in_parameter_declaration && ps.indent_parameters && ps.dec_nest == 0) {
     936            0 :         ps.ind_level = ps.i_l_follow = 1;
     937            0 :         ps.ind_stmt = 0;
     938              :         }
     939           87 :         ps.in_or_st = true; /* this might be a structure or initialization
     940              :                  * declaration */
     941           87 :         ps.in_decl = ps.decl_on_line = true;
     942           87 :         if ( /* !ps.in_or_st && */ ps.dec_nest <= 0)
     943           81 :         ps.just_saw_decl = 2;
     944           87 :         prefix_blankline_requested = 0;
     945          450 :         for (i = 0; token[i++];);   /* get length of token */
     946              : 
     947           87 :         if (ps.ind_level == 0 || ps.dec_nest > 0) {
     948              :         /* global variable or struct member in local variable */
     949           54 :         dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i;
     950           54 :         tabs_to_var = (use_tabs ? ps.decl_indent > 0 : 0);
     951              :         } else {
     952              :         /* local variable */
     953           33 :         dec_ind = ps.local_decl_indent > 0 ? ps.local_decl_indent : i;
     954           33 :         tabs_to_var = (use_tabs ? ps.local_decl_indent > 0 : 0);
     955              :         }
     956           87 :         goto copy_id;
     957              : 
     958          278 :     case funcname:
     959              :     case ident:     /* got an identifier or constant */
     960          278 :         if (ps.in_decl) {
     961          181 :         if (type_code == funcname) {
     962           21 :             ps.in_decl = false;
     963           21 :             if (procnames_start_line && s_code != e_code) {
     964           15 :             *e_code = '\0';
     965           15 :             dump_line();
     966              :             }
     967            6 :             else if (ps.want_blank) {
     968            0 :             *e_code++ = ' ';
     969              :             }
     970           21 :             ps.want_blank = false;
     971              :         }
     972          160 :         else if (!ps.block_init && !ps.dumped_decl_indent &&
     973           58 :             ps.paren_level == 0) { /* if we are in a declaration, we
     974              :                         * must indent identifier */
     975           50 :             indent_declaration(dec_ind, tabs_to_var);
     976           50 :             ps.dumped_decl_indent = true;
     977           50 :             ps.want_blank = false;
     978              :         }
     979              :         }
     980           97 :         else if (sp_sw && ps.p_l_follow == 0) {
     981            0 :         sp_sw = false;
     982            0 :         force_nl = true;
     983            0 :         ps.last_u_d = true;
     984            0 :         ps.in_stmt = false;
     985            0 :         parse(hd_type);
     986              :         }
     987           97 :     copy_id:
     988              :         {
     989          408 :         int len = e_token - s_token;
     990              : 
     991          408 :         CHECK_SIZE_CODE(len + 1);
     992          408 :         if (ps.want_blank)
     993          100 :             *e_code++ = ' ';
     994          408 :         memcpy(e_code, s_token, len);
     995          408 :         e_code += len;
     996              :         }
     997          408 :         if (type_code != funcname)
     998          386 :         ps.want_blank = true;
     999          408 :         break;
    1000              : 
    1001            2 :     case strpfx:
    1002              :         {
    1003            2 :         int len = e_token - s_token;
    1004              : 
    1005            2 :         CHECK_SIZE_CODE(len + 1);
    1006            2 :         if (ps.want_blank)
    1007            2 :             *e_code++ = ' ';
    1008            2 :         memcpy(e_code, token, len);
    1009            2 :         e_code += len;
    1010              :         }
    1011            2 :         ps.want_blank = false;
    1012            2 :         break;
    1013              : 
    1014            4 :     case period:        /* treat a period kind of like a binary
    1015              :                  * operation */
    1016            4 :         *e_code++ = '.';    /* move the period into line */
    1017            4 :         ps.want_blank = false;  /* dont put a blank after a period */
    1018            4 :         break;
    1019              : 
    1020           55 :     case comma:
    1021           55 :         ps.want_blank = (s_code != e_code); /* only put blank after comma
    1022              :                          * if comma does not start the
    1023              :                          * line */
    1024           55 :         if (ps.in_decl && ps.procname[0] == '\0' && !ps.block_init &&
    1025           24 :         !ps.dumped_decl_indent && ps.paren_level == 0) {
    1026              :         /* indent leading commas and not the actual identifiers */
    1027            2 :         indent_declaration(dec_ind - 1, tabs_to_var);
    1028            2 :         ps.dumped_decl_indent = true;
    1029              :         }
    1030           55 :         *e_code++ = ',';
    1031           55 :         if (ps.p_l_follow == 0) {
    1032           29 :         if (ps.block_init_level <= 0)
    1033           17 :             ps.block_init = 0;
    1034           29 :         if (break_comma && (!ps.leave_comma ||
    1035           12 :             count_spaces_until(compute_code_target(), s_code, e_code) >
    1036           12 :             max_col - tabsize))
    1037            1 :             force_nl = true;
    1038              :         }
    1039           55 :         break;
    1040              : 
    1041           11 :     case preesc:        /* got the character '#' */
    1042           11 :         if ((s_com != e_com) ||
    1043           11 :             (s_lab != e_lab) ||
    1044           11 :             (s_code != e_code))
    1045            0 :         dump_line();
    1046           11 :         CHECK_SIZE_LAB(1);
    1047           11 :         *e_lab++ = '#'; /* move whole line to 'label' buffer */
    1048              :         {
    1049           11 :         int         in_comment = 0;
    1050           11 :         int         com_start = 0;
    1051           11 :         char        quote = 0;
    1052           11 :         int         com_end = 0;
    1053              : 
    1054           22 :         while (*buf_ptr == ' ' || *buf_ptr == '\t') {
    1055            0 :             buf_ptr++;
    1056            0 :             if (buf_ptr >= buf_end)
    1057            0 :             fill_buffer();
    1058              :         }
    1059          181 :         while (*buf_ptr != '\n' || (in_comment && !had_eof)) {
    1060          170 :             CHECK_SIZE_LAB(2);
    1061          170 :             *e_lab = *buf_ptr++;
    1062          170 :             if (buf_ptr >= buf_end)
    1063            0 :             fill_buffer();
    1064          170 :             switch (*e_lab++) {
    1065            0 :             case BACKSLASH:
    1066            0 :             if (!in_comment) {
    1067            0 :                 *e_lab++ = *buf_ptr++;
    1068            0 :                 if (buf_ptr >= buf_end)
    1069            0 :                 fill_buffer();
    1070              :             }
    1071            0 :             break;
    1072            4 :             case '/':
    1073            4 :             if (*buf_ptr == '*' && !in_comment && !quote) {
    1074            4 :                 in_comment = 1;
    1075            4 :                 *e_lab++ = *buf_ptr++;
    1076            4 :                 com_start = e_lab - s_lab - 2;
    1077              :             }
    1078            4 :             break;
    1079            2 :             case '"':
    1080            2 :             if (quote == '"')
    1081            0 :                 quote = 0;
    1082            2 :             break;
    1083            0 :             case '\'':
    1084            0 :             if (quote == '\'')
    1085            0 :                 quote = 0;
    1086            0 :             break;
    1087            4 :             case '*':
    1088            4 :             if (*buf_ptr == '/' && in_comment) {
    1089            4 :                 in_comment = 0;
    1090            4 :                 *e_lab++ = *buf_ptr++;
    1091            4 :                 com_end = e_lab - s_lab;
    1092              :             }
    1093            4 :             break;
    1094              :             }
    1095              :         }
    1096              : 
    1097           11 :         while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
    1098            0 :             e_lab--;
    1099           11 :         if (e_lab - s_lab == com_end && bp_save == NULL) {
    1100              :             /* comment on preprocessor line */
    1101            4 :             if (sc_end == NULL) {   /* if this is the first comment,
    1102              :                          * we must set up the buffer */
    1103            4 :             save_com = sc_buf;
    1104            4 :             sc_end = &save_com[0];
    1105              :             }
    1106              :             else {
    1107            0 :             *sc_end++ = '\n';   /* add newline between
    1108              :                          * comments */
    1109            0 :             *sc_end++ = ' ';
    1110            0 :             --line_no;
    1111              :             }
    1112            4 :             if (sc_end - save_com + com_end - com_start > sc_size)
    1113            0 :             errx(1, "input too long");
    1114            4 :             memmove(sc_end, s_lab + com_start, com_end - com_start);
    1115            4 :             sc_end += com_end - com_start;
    1116            4 :             e_lab = s_lab + com_start;
    1117            9 :             while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
    1118            5 :             e_lab--;
    1119            4 :             bp_save = buf_ptr;  /* save current input buffer */
    1120            4 :             be_save = buf_end;
    1121            4 :             buf_ptr = save_com; /* fix so that subsequent calls to
    1122              :                      * lexi will take tokens out of
    1123              :                      * save_com */
    1124            4 :             *sc_end++ = ' ';    /* add trailing blank, just in case */
    1125            4 :             buf_end = sc_end;
    1126            4 :             sc_end = NULL;
    1127              :         }
    1128           11 :         CHECK_SIZE_LAB(1);
    1129           11 :         *e_lab = '\0';  /* null terminate line */
    1130           11 :         ps.pcase = false;
    1131              :         }
    1132              : 
    1133           11 :         if (strncmp(s_lab, "#if", 3) == 0) { /* also ifdef, ifndef */
    1134            2 :         if ((size_t)ifdef_level < nitems(state_stack)) {
    1135            2 :             match_state[ifdef_level].tos = -1;
    1136            2 :             state_stack[ifdef_level++] = ps;
    1137              :         }
    1138              :         else
    1139            0 :             diag2(1, "#if stack overflow");
    1140              :         }
    1141            9 :         else if (strncmp(s_lab, "#el", 3) == 0) { /* else, elif */
    1142            4 :         if (ifdef_level <= 0)
    1143            0 :             diag2(1, s_lab[3] == 'i' ? "Unmatched #elif" : "Unmatched #else");
    1144              :         else {
    1145            4 :             match_state[ifdef_level - 1] = ps;
    1146            4 :             ps = state_stack[ifdef_level - 1];
    1147              :         }
    1148              :         }
    1149            5 :         else if (strncmp(s_lab, "#endif", 6) == 0) {
    1150            2 :         if (ifdef_level <= 0)
    1151            0 :             diag2(1, "Unmatched #endif");
    1152              :         else
    1153            2 :             ifdef_level--;
    1154              :         } else {
    1155              :         struct directives {
    1156              :             int size;
    1157              :             const char *string;
    1158              :         }
    1159            3 :         recognized[] = {
    1160              :             {7, "include"},
    1161              :             {6, "define"},
    1162              :             {5, "undef"},
    1163              :             {4, "line"},
    1164              :             {5, "error"},
    1165              :             {6, "pragma"}
    1166              :         };
    1167            3 :         int d = nitems(recognized);
    1168           13 :         while (--d >= 0)
    1169           13 :             if (strncmp(s_lab + 1, recognized[d].string, recognized[d].size) == 0)
    1170            3 :             break;
    1171            3 :         if (d < 0) {
    1172            0 :             diag2(1, "Unrecognized cpp directive");
    1173            0 :             break;
    1174              :         }
    1175              :         }
    1176           11 :         if (blanklines_around_conditional_compilation) {
    1177            0 :         postfix_blankline_requested++;
    1178            0 :         n_real_blanklines = 0;
    1179              :         }
    1180              :         else {
    1181           11 :         postfix_blankline_requested = 0;
    1182           11 :         prefix_blankline_requested = 0;
    1183              :         }
    1184           11 :         break;      /* subsequent processing of the newline
    1185              :                  * character will cause the line to be printed */
    1186              : 
    1187           58 :     case comment:       /* we have gotten a / followed by * this is a biggie */
    1188           58 :         pr_comment();
    1189           58 :         break;
    1190              :     }           /* end of big switch stmt */
    1191              : 
    1192         1214 :     *e_code = '\0';     /* make sure code section is null terminated */
    1193         1214 :     if (type_code != comment && type_code != newline && type_code != preesc)
    1194          866 :         ps.last_token = type_code;
    1195              :     }               /* end of main while (1) loop */
    1196              : }
    1197              : 
    1198              : /*
    1199              :  * copy input file to backup file if in_name is /blah/blah/blah/file, then
    1200              :  * backup file will be ".Bfile" then make the backup file the input and
    1201              :  * original input file the output
    1202              :  */
    1203              : static void
    1204            0 : bakcopy(void)
    1205              : {
    1206              :     int         n,
    1207              :                 bakchn;
    1208              :     char        buff[8 * 1024];
    1209              :     const char *p;
    1210              : 
    1211              :     /* construct file name .Bfile */
    1212            0 :     for (p = in_name; *p; p++); /* skip to end of string */
    1213            0 :     while (p > in_name && *p != '/') /* find last '/' */
    1214            0 :     p--;
    1215            0 :     if (*p == '/')
    1216            0 :     p++;
    1217            0 :     sprintf(bakfile, "%s.BAK", p);
    1218              : 
    1219              :     /* copy in_name to backup file */
    1220            0 :     bakchn = creat(bakfile, 0600);
    1221            0 :     if (bakchn < 0)
    1222            0 :     err(1, "%s", bakfile);
    1223            0 :     while ((n = read(fileno(input), buff, sizeof(buff))) > 0)
    1224            0 :     if (write(bakchn, buff, n) != n)
    1225            0 :         err(1, "%s", bakfile);
    1226            0 :     if (n < 0)
    1227            0 :     err(1, "%s", in_name);
    1228            0 :     close(bakchn);
    1229            0 :     fclose(input);
    1230              : 
    1231              :     /* re-open backup file as the input file */
    1232            0 :     input = fopen(bakfile, "r");
    1233            0 :     if (input == NULL)
    1234            0 :     err(1, "%s", bakfile);
    1235              :     /* now the original input file will be the output */
    1236            0 :     output = fopen(in_name, "wb");
    1237            0 :     if (output == NULL) {
    1238            0 :     unlink(bakfile);
    1239            0 :     err(1, "%s", in_name);
    1240              :     }
    1241            0 : }
    1242              : 
    1243              : static void
    1244           69 : indent_declaration(int cur_dec_ind, int tabs_to_var)
    1245              : {
    1246           69 :     int pos = e_code - s_code;
    1247           69 :     char *startpos = e_code;
    1248              : 
    1249              :     /*
    1250              :      * get the tab math right for indentations that are not multiples of tabsize
    1251              :      */
    1252           69 :     if ((ps.ind_level * ps.ind_size) % tabsize != 0) {
    1253            0 :     pos += (ps.ind_level * ps.ind_size) % tabsize;
    1254            0 :     cur_dec_ind += (ps.ind_level * ps.ind_size) % tabsize;
    1255              :     }
    1256           69 :     if (tabs_to_var) {
    1257              :     int tpos;
    1258              : 
    1259           69 :     CHECK_SIZE_CODE(cur_dec_ind / tabsize);
    1260          164 :     while ((tpos = tabsize * (1 + pos / tabsize)) <= cur_dec_ind) {
    1261           95 :         *e_code++ = (!postgres_tab_rules ||
    1262            0 :              tpos != pos + 1 ||
    1263            0 :              cur_dec_ind >= tpos + tabsize) ? '\t' : ' ';
    1264           95 :         pos = tpos;
    1265              :     }
    1266              :     }
    1267           69 :     CHECK_SIZE_CODE(cur_dec_ind - pos + 1);
    1268          157 :     while (pos < cur_dec_ind) {
    1269           88 :     *e_code++ = ' ';
    1270           88 :     pos++;
    1271              :     }
    1272           69 :     if (e_code == startpos && ps.want_blank) {
    1273            2 :     *e_code++ = ' ';
    1274            2 :     ps.want_blank = false;
    1275              :     }
    1276           69 : }
        

Generated by: LCOV version 2.0-1