LCOV - differential code coverage report
Current view: top level - src/tools/pg_bsd_indent - indent.c (source / functions) Coverage Total Hit UNC GNC
Current: Differential Code Coverage HEAD vs 15 Lines: 77.0 % 732 564 168 564
Current Date: 2023-04-08 15:15:32 Functions: 66.7 % 3 2 1 2
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

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

Generated by: LCOV version v1.16-55-g56c0a2a