indent.c revision 99112
1233294Sstas/* 2102644Snectar * Copyright (c) 1985 Sun Microsystems, Inc. 355682Smarkm * Copyright (c) 1976 Board of Trustees of the University of Illinois. 4142403Snectar * Copyright (c) 1980, 1993 5233294Sstas * The Regents of the University of California. All rights reserved. 6233294Sstas * 755682Smarkm * Redistribution and use in source and binary forms, with or without 855682Smarkm * modification, are permitted provided that the following conditions 955682Smarkm * are met: 1055682Smarkm * 1. Redistributions of source code must retain the above copyright 1155682Smarkm * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1355682Smarkm * notice, this list of conditions and the following disclaimer in the 1455682Smarkm * documentation and/or other materials provided with the distribution. 1555682Smarkm * 3. All advertising materials mentioning features or use of this software 1690926Snectar * must display the following acknowledgement: 1790926Snectar * This product includes software developed by the University of 18233294Sstas * California, Berkeley and its contributors. 1990926Snectar * 4. Neither the name of the University nor the names of its contributors 20233294Sstas * may be used to endorse or promote products derived from this software 2190926Snectar * without specific prior written permission. 22233294Sstas * 2355682Smarkm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2455682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2555682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2755682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29102644Snectar * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30102644Snectar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31102644Snectar * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32127808Snectar * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3390926Snectar * SUCH DAMAGE. 34127808Snectar */ 3555682Smarkm 3655682Smarkm#ifndef lint 3755682Smarkmstatic const char copyright[] = 3855682Smarkm"@(#) Copyright (c) 1985 Sun Microsystems, Inc.\n\ 3955682Smarkm@(#) Copyright (c) 1976 Board of Trustees of the University of Illinois.\n\ 4055682Smarkm@(#) Copyright (c) 1980, 1993\n\ 41178825Sdfr The Regents of the University of California. All rights reserved.\n"; 4255682Smarkm#endif /* not lint */ 43142403Snectar 44142403Snectar#ifndef lint 45142403Snectar#if 0 46233294Sstasstatic char sccsid[] = "@(#)indent.c 5.17 (Berkeley) 6/7/93"; 47233294Sstas#endif 48178825Sdfr#endif /* not lint */ 49142403Snectar#include <sys/cdefs.h> 50233294Sstas__FBSDID("$FreeBSD: head/usr.bin/indent/indent.c 99112 2002-06-30 05:25:07Z obrien $"); 51142403Snectar 52142403Snectar#include <sys/param.h> 53142403Snectar#include <err.h> 54233294Sstas#include <fcntl.h> 55142403Snectar#include <unistd.h> 56142403Snectar#include <stdio.h> 57142403Snectar#include <stdlib.h> 58142403Snectar#include <string.h> 59142403Snectar#include <ctype.h> 60142403Snectar#include "indent_globs.h" 61142403Snectar#include "indent_codes.h" 62142403Snectar#include "indent.h" 63142403Snectar 64142403Snectarstatic void bakcopy(void); 65142403Snectar 66142403Snectarconst char *in_name = "Standard Input"; /* will always point to name of input 67142403Snectar * file */ 68142403Snectarconst char *out_name = "Standard Output"; /* will always point to name 69233294Sstas * of output file */ 70142403Snectarchar bakfile[MAXPATHLEN] = ""; 71142403Snectar 72142403Snectarint 73142403Snectarmain(int argc, char **argv) 74178825Sdfr{ 75142403Snectar 76142403Snectar extern int found_err; /* flag set in diagN() on error */ 77142403Snectar int dec_ind; /* current indentation for declarations */ 78142403Snectar int di_stack[20]; /* a stack of structure indentation levels */ 79142403Snectar int flushed_nl; /* used when buffering up comments to remember 80142403Snectar * that a newline was passed over */ 81142403Snectar int force_nl; /* when true, code must be broken */ 82142403Snectar int hd_type = 0; /* used to store type of stmt for if (...), 83233294Sstas * for (...), etc */ 84233294Sstas int i; /* local loop counter */ 85233294Sstas int scase; /* set to true when we see a case, so we will 86233294Sstas * know what to do with the following colon */ 87233294Sstas int sp_sw; /* when true, we are in the expressin of 88233294Sstas * if(...), while(...), etc. */ 89178825Sdfr int squest; /* when this is positive, we have seen a ? 90178825Sdfr * without the matching : in a <c>?<s>:<s> 91178825Sdfr * construct */ 92178825Sdfr const char *t_ptr; /* used for copying tokens */ 93178825Sdfr int type_code; /* the type of token, returned by lexi */ 94178825Sdfr 95178825Sdfr int last_else = 0; /* true iff last keyword was an else */ 96233294Sstas 97142403Snectar 98142403Snectar /*-----------------------------------------------*\ 99178825Sdfr | INITIALIZATION | 100142403Snectar \*-----------------------------------------------*/ 101142403Snectar 102233294Sstas 103178825Sdfr ps.p_stack[0] = stmt; /* this is the parser's stack */ 104233294Sstas ps.last_nl = true; /* this is true if the last thing scanned was 105178825Sdfr * a newline */ 106142403Snectar ps.last_token = semicolon; 107142403Snectar combuf = (char *) malloc(bufsize); 108142403Snectar labbuf = (char *) malloc(bufsize); 109233294Sstas codebuf = (char *) malloc(bufsize); 110142403Snectar tokenbuf = (char *) malloc(bufsize); 111142403Snectar l_com = combuf + bufsize - 5; 112142403Snectar l_lab = labbuf + bufsize - 5; 113233294Sstas l_code = codebuf + bufsize - 5; 114233294Sstas l_token = tokenbuf + bufsize - 5; 115233294Sstas combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and 116233294Sstas * comment buffers */ 117233294Sstas combuf[1] = codebuf[1] = labbuf[1] = '\0'; 118233294Sstas ps.else_if = 1; /* Default else-if special processing to on */ 119233294Sstas s_lab = e_lab = labbuf + 1; 120233294Sstas s_code = e_code = codebuf + 1; 121233294Sstas s_com = e_com = combuf + 1; 122233294Sstas s_token = e_token = tokenbuf + 1; 123233294Sstas 124233294Sstas in_buffer = (char *) malloc(10); 125233294Sstas in_buffer_limit = in_buffer + 8; 126142403Snectar buf_ptr = buf_end = in_buffer; 127142403Snectar line_no = 1; 128142403Snectar had_eof = ps.in_decl = ps.decl_on_line = break_comma = false; 129142403Snectar sp_sw = force_nl = false; 130142403Snectar ps.in_or_st = false; 131142403Snectar ps.bl_line = true; 132142403Snectar dec_ind = 0; 133142403Snectar di_stack[ps.dec_nest = 0] = 0; 134178825Sdfr ps.want_blank = ps.in_stmt = ps.ind_stmt = false; 135178825Sdfr 136178825Sdfr 137178825Sdfr scase = ps.pcase = false; 138178825Sdfr squest = 0; 139142403Snectar sc_end = 0; 140178825Sdfr bp_save = 0; 141178825Sdfr be_save = 0; 142142403Snectar 143142403Snectar output = 0; 144142403Snectar 145142403Snectar 146142403Snectar 147142403Snectar /*--------------------------------------------------*\ 148178825Sdfr | COMMAND LINE SCAN | 149178825Sdfr \*--------------------------------------------------*/ 150178825Sdfr 151142403Snectar#ifdef undef 152142403Snectar max_col = 78; /* -l78 */ 153142403Snectar lineup_to_parens = 1; /* -lp */ 154178825Sdfr ps.ljust_decl = 0; /* -ndj */ 155178825Sdfr ps.com_ind = 33; /* -c33 */ 156233294Sstas star_comment_cont = 1; /* -sc */ 157233294Sstas ps.ind_size = 8; /* -i8 */ 158142403Snectar verbose = 0; 159142403Snectar ps.decl_indent = 16; /* -di16 */ 160142403Snectar ps.indent_parameters = 1; /* -ip */ 161142403Snectar ps.decl_com_ind = 0; /* if this is not set to some positive value 162142403Snectar * by an arg, we will set this equal to 163142403Snectar * ps.com_ind */ 164233294Sstas btype_2 = 1; /* -br */ 165233294Sstas cuddle_else = 1; /* -ce */ 166233294Sstas ps.unindent_displace = 0; /* -d0 */ 167142403Snectar ps.case_indent = 0; /* -cli0 */ 168142403Snectar format_block_comments = 1; /* -fcb */ 169178825Sdfr format_col1_comments = 1; /* -fc1 */ 170178825Sdfr procnames_start_line = 1; /* -psl */ 171178825Sdfr proc_calls_space = 0; /* -npcs */ 172142403Snectar comment_delimiter_on_blankline = 1; /* -cdb */ 173178825Sdfr ps.leave_comma = 1; /* -nbc */ 174178825Sdfr#endif 175178825Sdfr 176233294Sstas for (i = 1; i < argc; ++i) 177233294Sstas if (strcmp(argv[i], "-npro") == 0) 178233294Sstas break; 179233294Sstas set_defaults(); 180233294Sstas if (i >= argc) 181233294Sstas set_profile(); 182233294Sstas 183233294Sstas for (i = 1; i < argc; ++i) { 184233294Sstas 185233294Sstas /* 186233294Sstas * look thru args (if any) for changes to defaults 187233294Sstas */ 188233294Sstas if (argv[i][0] != '-') {/* no flag on parameter */ 189233294Sstas if (input == 0) { /* we must have the input file */ 190233294Sstas in_name = argv[i]; /* remember name of input file */ 191233294Sstas input = fopen(in_name, "r"); 192233294Sstas if (input == 0) /* check for open error */ 193233294Sstas err(1, "%s", in_name); 194233294Sstas continue; 195233294Sstas } 196233294Sstas else if (output == 0) { /* we have the output file */ 197233294Sstas out_name = argv[i]; /* remember name of output file */ 198233294Sstas if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite 199233294Sstas * the file */ 200233294Sstas errx(1, "input and output files must be different"); 201233294Sstas } 202233294Sstas output = fopen(out_name, "w"); 203233294Sstas if (output == 0) /* check for create error */ 204142403Snectar err(1, "%s", out_name); 205233294Sstas continue; 206142403Snectar } 207142403Snectar errx(1, "unknown parameter: %s", argv[i]); 208142403Snectar } 209142403Snectar else 210127808Snectar set_option(argv[i]); 21155682Smarkm } /* end of for */ 21272445Sassar if (input == 0) 213127808Snectar input = stdin; 214233294Sstas if (output == 0) { 215233294Sstas if (troff || input == stdin) 216127808Snectar output = stdout; 217127808Snectar else { 218127808Snectar out_name = in_name; 21955682Smarkm bakcopy(); 22055682Smarkm } 221233294Sstas } 222233294Sstas if (ps.com_ind <= 1) 22355682Smarkm ps.com_ind = 2; /* dont put normal comments before column 2 */ 22455682Smarkm if (troff) { 22555682Smarkm if (bodyf.font[0] == 0) 226233294Sstas parsefont(&bodyf, "R"); 227127808Snectar if (scomf.font[0] == 0) 22890926Snectar parsefont(&scomf, "I"); 22972445Sassar if (blkcomf.font[0] == 0) 230127808Snectar blkcomf = scomf, blkcomf.size += 2; 231127808Snectar if (boxcomf.font[0] == 0) 232233294Sstas boxcomf = blkcomf; 23355682Smarkm if (stringf.font[0] == 0) 234127808Snectar parsefont(&stringf, "L"); 235233294Sstas if (keywordf.font[0] == 0) 23690926Snectar parsefont(&keywordf, "B"); 237178825Sdfr writefdef(&bodyf, 'B'); 238178825Sdfr writefdef(&scomf, 'C'); 23972445Sassar writefdef(&blkcomf, 'L'); 240233294Sstas writefdef(&boxcomf, 'X'); 241233294Sstas writefdef(&stringf, 'S'); 242233294Sstas writefdef(&keywordf, 'K'); 243127808Snectar } 244127808Snectar if (block_comment_max_col <= 0) 245127808Snectar block_comment_max_col = max_col; 246127808Snectar if (ps.decl_com_ind <= 0) /* if not specified by user, set this */ 247127808Snectar ps.decl_com_ind = ps.ljust_decl ? (ps.com_ind <= 10 ? 2 : ps.com_ind - 8) : ps.com_ind; 248233294Sstas if (continuation_indent == 0) 249178825Sdfr continuation_indent = ps.ind_size; 25055682Smarkm fill_buffer(); /* get first batch of stuff into input buffer */ 25172445Sassar 252178825Sdfr parse(semicolon); 253127808Snectar { 254127808Snectar char *p = buf_ptr; 255233294Sstas int col = 1; 256233294Sstas 257127808Snectar while (1) { 258127808Snectar if (*p == ' ') 259233294Sstas col++; 260178825Sdfr else if (*p == '\t') 261127808Snectar col = ((col - 1) & ~7) + 9; 262127808Snectar else 263127808Snectar break; 26490926Snectar p++; 265233294Sstas } 266127808Snectar if (col > ps.ind_size) 267178825Sdfr ps.ind_level = ps.i_l_follow = col / ps.ind_size; 26855682Smarkm } 269102644Snectar if (troff) { 270102644Snectar const char *p = in_name, 271178825Sdfr *beg = in_name; 272127808Snectar 273127808Snectar while (*p) 27455682Smarkm if (*p++ == '/') 27555682Smarkm beg = p; 27690926Snectar fprintf(output, ".Fn \"%s\"\n", beg); 277127808Snectar } 278127808Snectar /* 279127808Snectar * START OF MAIN LOOP 280127808Snectar */ 281127808Snectar 28290926Snectar while (1) { /* this is the main loop. it will go until we 28390926Snectar * reach eof */ 28490926Snectar int is_procname; 285127808Snectar 286127808Snectar type_code = lexi(); /* lexi reads one token. The actual 287127808Snectar * characters read are stored in "token". lexi 288127808Snectar * returns a code indicating the type of token */ 289233294Sstas is_procname = ps.procname[0]; 290127808Snectar 291127808Snectar /* 292233294Sstas * The following code moves everything following an if (), while (), 293178825Sdfr * else, etc. up to the start of the following stmt to a buffer. This 294127808Snectar * allows proper handling of both kinds of brace placement. 295127808Snectar */ 296127808Snectar 297127808Snectar flushed_nl = false; 298127808Snectar while (ps.search_brace) { /* if we scanned an if(), while(), 299127808Snectar * etc., we might need to copy stuff 300127808Snectar * into a buffer we must loop, copying 301127808Snectar * stuff into save_com, until we find 302178825Sdfr * the start of the stmt which follows 303178825Sdfr * the if, or whatever */ 304178825Sdfr switch (type_code) { 305178825Sdfr case newline: 306127808Snectar ++line_no; 307127808Snectar flushed_nl = true; 30855682Smarkm case form_feed: 309127808Snectar break; /* form feeds and newlines found here will be 310233294Sstas * ignored */ 311233294Sstas 312127808Snectar case lbrace: /* this is a brace that starts the compound 313127808Snectar * stmt */ 314127808Snectar if (sc_end == 0) { /* ignore buffering if a comment wasnt 315127808Snectar * stored up */ 316127808Snectar ps.search_brace = false; 31755682Smarkm goto check_type; 318127808Snectar } 319127808Snectar if (btype_2) { 320178825Sdfr save_com[0] = '{'; /* we either want to put the brace 321127808Snectar * right after the if */ 322127808Snectar goto sw_buffer; /* go to common code to get out of 32355682Smarkm * this loop */ 32455682Smarkm } 325127808Snectar case comment: /* we have a comment, so we must copy it into 326127808Snectar * the buffer */ 327233294Sstas if (!flushed_nl || sc_end != 0) { 328127808Snectar if (sc_end == 0) { /* if this is the first comment, we 329127808Snectar * must set up the buffer */ 330233294Sstas save_com[0] = save_com[1] = ' '; 33155682Smarkm sc_end = &(save_com[2]); 33255682Smarkm } 333120945Snectar else { 334127808Snectar *sc_end++ = '\n'; /* add newline between 335233294Sstas * comments */ 336178825Sdfr *sc_end++ = ' '; 337233294Sstas --line_no; 338233294Sstas } 339233294Sstas *sc_end++ = '/'; /* copy in start of comment */ 34055682Smarkm *sc_end++ = '*'; 341233294Sstas 342127808Snectar for (;;) { /* loop until we get to the end of the comment */ 343233294Sstas *sc_end = *buf_ptr++; 344233294Sstas if (buf_ptr >= buf_end) 34555682Smarkm fill_buffer(); 346127808Snectar 347127808Snectar if (*sc_end++ == '*' && *buf_ptr == '/') 348127808Snectar break; /* we are at end of comment */ 349127808Snectar 350233294Sstas if (sc_end >= &(save_com[sc_size])) { /* check for temp buffer 351127808Snectar * overflow */ 352127808Snectar diag2(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever."); 353233294Sstas fflush(output); 354233294Sstas exit(1); 355233294Sstas } 356233294Sstas } 35755682Smarkm *sc_end++ = '/'; /* add ending slash */ 358233294Sstas if (++buf_ptr >= buf_end) /* get past / in buffer */ 359127808Snectar fill_buffer(); 360127808Snectar break; 361233294Sstas } 362233294Sstas default: /* it is the start of a normal statment */ 363102644Snectar if (flushed_nl) /* if we flushed a newline, make sure it is 36455682Smarkm * put back */ 365178825Sdfr force_nl = true; 36655682Smarkm if ((type_code == sp_paren && *token == 'i' 36755682Smarkm && last_else && ps.else_if) 36855682Smarkm || (type_code == sp_nparen && *token == 'e' 369178825Sdfr && e_code != s_code && e_code[-1] == '}')) 37090926Snectar force_nl = false; 37190926Snectar 37290926Snectar if (sc_end == 0) { /* ignore buffering if comment wasnt 37390926Snectar * saved up */ 37455682Smarkm ps.search_brace = false; 375178825Sdfr goto check_type; 376178825Sdfr } 377178825Sdfr if (force_nl) { /* if we should insert a nl here, put it into 378178825Sdfr * the buffer */ 379178825Sdfr force_nl = false; 380233294Sstas --line_no; /* this will be re-increased when the nl is 381127808Snectar * read from the buffer */ 382233294Sstas *sc_end++ = '\n'; 383233294Sstas *sc_end++ = ' '; 384127808Snectar if (verbose && !flushed_nl) /* print error msg if the line 385233294Sstas * was not already broken */ 386178825Sdfr diag2(0, "Line broken"); 387178825Sdfr flushed_nl = false; 388127808Snectar } 389127808Snectar for (t_ptr = token; *t_ptr; ++t_ptr) 390127808Snectar *sc_end++ = *t_ptr; /* copy token into temp buffer */ 391127808Snectar ps.procname[0] = 0; 392127808Snectar 393127808Snectar sw_buffer: 394178825Sdfr ps.search_brace = false; /* stop looking for start of 395127808Snectar * stmt */ 396178825Sdfr bp_save = buf_ptr; /* save current input buffer */ 397178825Sdfr be_save = buf_end; 398102644Snectar buf_ptr = save_com; /* fix so that subsequent calls to 399102644Snectar * lexi will take tokens out of 400102644Snectar * save_com */ 401178825Sdfr *sc_end++ = ' ';/* add trailing blank, just in case */ 402127808Snectar buf_end = sc_end; 403127808Snectar sc_end = 0; 404127808Snectar break; 405127808Snectar } /* end of switch */ 406127808Snectar if (type_code != 0) /* we must make this check, just in case there 407127808Snectar * was an unexpected EOF */ 408178825Sdfr type_code = lexi(); /* read another token */ 409127808Snectar /* if (ps.search_brace) ps.procname[0] = 0; */ 410127808Snectar if ((is_procname = ps.procname[0]) && flushed_nl 41172445Sassar && !procnames_start_line && ps.in_decl 412127808Snectar && type_code == ident) 413127808Snectar flushed_nl = 0; 414178825Sdfr } /* end of while (search_brace) */ 415127808Snectar last_else = 0; 416127808Snectarcheck_type: 417142403Snectar if (type_code == 0) { /* we got eof */ 418127808Snectar if (s_lab != e_lab || s_code != e_code 419178825Sdfr || s_com != e_com) /* must dump end of line */ 420127808Snectar dump_line(); 421127808Snectar if (ps.tos > 1) /* check for balanced braces */ 422178825Sdfr diag2(1, "Stuff missing from end of file."); 423127808Snectar 424127808Snectar if (verbose) { 425178825Sdfr printf("There were %d output lines and %d comments\n", 426233294Sstas ps.out_lines, ps.out_coms); 427127808Snectar printf("(Lines with comments)/(Lines with code): %6.3f\n", 428127808Snectar (1.0 * ps.com_lines) / code_lines); 429233294Sstas } 430178825Sdfr fflush(output); 431178825Sdfr exit(found_err); 432233294Sstas } 433233294Sstas if ( 434233294Sstas (type_code != comment) && 435233294Sstas (type_code != newline) && 436233294Sstas (type_code != preesc) && 437102644Snectar (type_code != form_feed)) { 43890926Snectar if (force_nl && 43972445Sassar (type_code != semicolon) && 44055682Smarkm (type_code != lbrace || !btype_2)) { 441233294Sstas /* we should force a broken line here */ 44255682Smarkm if (verbose && !flushed_nl) 44355682Smarkm diag2(0, "Line broken"); 44455682Smarkm flushed_nl = false; 44555682Smarkm dump_line(); 44655682Smarkm ps.want_blank = false; /* dont insert blank at line start */ 44755682Smarkm force_nl = false; 448233294Sstas } 44955682Smarkm ps.in_stmt = true; /* turn on flag which causes an extra level of 450120945Snectar * indentation. this is turned off by a ; or 45190926Snectar * '}' */ 45272445Sassar if (s_com != e_com) { /* the turkey has embedded a comment 45355682Smarkm * in a line. fix it */ 45490926Snectar *e_code++ = ' '; 455233294Sstas for (t_ptr = s_com; *t_ptr; ++t_ptr) { 45690926Snectar CHECK_SIZE_CODE; 457178825Sdfr *e_code++ = *t_ptr; 458178825Sdfr } 459178825Sdfr *e_code++ = ' '; 460178825Sdfr *e_code = '\0'; /* null terminate code sect */ 461233294Sstas ps.want_blank = false; 462233294Sstas e_com = s_com; 463178825Sdfr } 464233294Sstas } 465178825Sdfr else if (type_code != comment) /* preserve force_nl thru a comment */ 46690926Snectar force_nl = false; /* cancel forced newline after newline, form 46772445Sassar * feed, etc */ 46872445Sassar 469178825Sdfr 470178825Sdfr 47172445Sassar /*-----------------------------------------------------*\ 472233294Sstas | do switch on type of token scanned | 47372445Sassar \*-----------------------------------------------------*/ 47455682Smarkm CHECK_SIZE_CODE; 47590926Snectar switch (type_code) { /* now, decide what to do with the token */ 476178825Sdfr 477233294Sstas case form_feed: /* found a form feed in line */ 478233294Sstas ps.use_ff = true; /* a form feed is treated much like a newline */ 479233294Sstas dump_line(); 480233294Sstas ps.want_blank = false; 481233294Sstas break; 482233294Sstas 483233294Sstas case newline: 484178825Sdfr if (ps.last_token != comma || ps.p_l_follow > 0 485178825Sdfr || !ps.leave_comma || ps.block_init || !break_comma || s_com != e_com) { 486178825Sdfr dump_line(); 487178825Sdfr ps.want_blank = false; 488178825Sdfr } 489178825Sdfr ++line_no; /* keep track of input line number */ 490178825Sdfr break; 491178825Sdfr 492178825Sdfr case lparen: /* got a '(' or '[' */ 493178825Sdfr ++ps.p_l_follow; /* count parens to make Healy happy */ 494233294Sstas if (ps.want_blank && *token != '[' && 495233294Sstas (ps.last_token != ident || proc_calls_space 496233294Sstas || (ps.its_a_keyword && (!ps.sizeof_keyword || Bill_Shannon)))) 497233294Sstas *e_code++ = ' '; 49872445Sassar if (ps.in_decl && !ps.block_init) 49972445Sassar if (troff && !ps.dumped_decl_indent && !is_procname && ps.last_token == decl) { 500178825Sdfr ps.dumped_decl_indent = 1; 50172445Sassar sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); 50272445Sassar e_code += strlen(e_code); 50355682Smarkm } 504233294Sstas else { 505233294Sstas while ((e_code - s_code) < dec_ind) { 506233294Sstas CHECK_SIZE_CODE; 507233294Sstas *e_code++ = ' '; 508233294Sstas } 509233294Sstas *e_code++ = token[0]; 510233294Sstas } 511233294Sstas else 512233294Sstas *e_code++ = token[0]; 51390926Snectar ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code; 51455682Smarkm if (sp_sw && ps.p_l_follow == 1 && extra_expression_indent 51555682Smarkm && ps.paren_indents[0] < 2 * ps.ind_size) 516233294Sstas ps.paren_indents[0] = 2 * ps.ind_size; 517142403Snectar ps.want_blank = false; 518142403Snectar if (ps.in_or_st && *token == '(' && ps.tos <= 2) { 519142403Snectar /* 520142403Snectar * this is a kluge to make sure that declarations will be 521233294Sstas * aligned right if proc decl has an explicit type on it, i.e. 522233294Sstas * "int a(x) {..." 523142403Snectar */ 524142403Snectar parse(semicolon); /* I said this was a kluge... */ 525142403Snectar ps.in_or_st = false; /* turn off flag for structure decl or 526233294Sstas * initialization */ 527233294Sstas } 528233294Sstas if (ps.sizeof_keyword) 529142403Snectar ps.sizeof_mask |= 1 << ps.p_l_follow; 530142403Snectar break; 531142403Snectar 532142403Snectar case rparen: /* got a ')' or ']' */ 533142403Snectar rparen_count--; 534142403Snectar if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask) { 535142403Snectar ps.last_u_d = true; 536142403Snectar ps.cast_mask &= (1 << ps.p_l_follow) - 1; 537142403Snectar ps.want_blank = false; 538142403Snectar } else 539142403Snectar ps.want_blank = true; 540142403Snectar ps.sizeof_mask &= (1 << ps.p_l_follow) - 1; 541142403Snectar if (--ps.p_l_follow < 0) { 542142403Snectar ps.p_l_follow = 0; 543142403Snectar diag3(0, "Extra %c", *token); 544142403Snectar } 545142403Snectar if (e_code == s_code) /* if the paren starts the line */ 546233294Sstas ps.paren_level = ps.p_l_follow; /* then indent it */ 54755682Smarkm 54855682Smarkm *e_code++ = token[0]; 549178825Sdfr 550233294Sstas if (sp_sw && (ps.p_l_follow == 0)) { /* check for end of if 551233294Sstas * (...), or some such */ 552233294Sstas sp_sw = false; 553233294Sstas force_nl = true;/* must force newline after if */ 554233294Sstas ps.last_u_d = true; /* inform lexi that a following 555233294Sstas * operator is unary */ 556233294Sstas ps.in_stmt = false; /* dont use stmt continuation 557233294Sstas * indentation */ 558233294Sstas 559233294Sstas parse(hd_type); /* let parser worry about if, or whatever */ 560233294Sstas } 561233294Sstas ps.search_brace = btype_2; /* this should insure that constructs 562233294Sstas * such as main(){...} and int[]{...} 563233294Sstas * have their braces put in the right 564233294Sstas * place */ 565233294Sstas break; 566233294Sstas 567233294Sstas case unary_op: /* this could be any unary operation */ 568233294Sstas if (ps.want_blank) 569233294Sstas *e_code++ = ' '; 570233294Sstas 57155682Smarkm if (troff && !ps.dumped_decl_indent && ps.in_decl && !is_procname) { 57255682Smarkm sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); 57355682Smarkm ps.dumped_decl_indent = 1; 574233294Sstas e_code += strlen(e_code); 575233294Sstas } 576233294Sstas else { 577233294Sstas const char *res = token; 578233294Sstas 579233294Sstas if (ps.in_decl && !ps.block_init) { /* if this is a unary op 580233294Sstas * in a declaration, we 58155682Smarkm * should indent this 58290926Snectar * token */ 583233294Sstas for (i = 0; token[i]; ++i); /* find length of token */ 584233294Sstas while ((e_code - s_code) < (dec_ind - i)) { 585233294Sstas CHECK_SIZE_CODE; 586233294Sstas *e_code++ = ' '; /* pad it */ 587233294Sstas } 588233294Sstas } 589233294Sstas if (troff && token[0] == '-' && token[1] == '>') 590178825Sdfr res = "\\(->"; 591178825Sdfr for (t_ptr = res; *t_ptr; ++t_ptr) { 592178825Sdfr CHECK_SIZE_CODE; 593233294Sstas *e_code++ = *t_ptr; 594233294Sstas } 595233294Sstas } 596233294Sstas ps.want_blank = false; 597233294Sstas break; 598233294Sstas 599233294Sstas case binary_op: /* any binary operation */ 600233294Sstas if (ps.want_blank) 601233294Sstas *e_code++ = ' '; 602233294Sstas { 603233294Sstas const char *res = token; 604233294Sstas 605233294Sstas if (troff) 606233294Sstas switch (token[0]) { 607233294Sstas case '<': 608233294Sstas if (token[1] == '=') 609233294Sstas res = "\\(<="; 610233294Sstas break; 611233294Sstas case '>': 612233294Sstas if (token[1] == '=') 613233294Sstas res = "\\(>="; 61455682Smarkm break; 615178825Sdfr case '!': 616178825Sdfr if (token[1] == '=') 617233294Sstas res = "\\(!="; 618233294Sstas break; 619233294Sstas case '|': 620233294Sstas if (token[1] == '|') 621233294Sstas res = "\\(br\\(br"; 622233294Sstas else if (token[1] == 0) 623233294Sstas res = "\\(br"; 624178825Sdfr break; 625178825Sdfr } 626233294Sstas for (t_ptr = res; *t_ptr; ++t_ptr) { 627233294Sstas CHECK_SIZE_CODE; 628233294Sstas *e_code++ = *t_ptr; /* move the operator */ 629233294Sstas } 630233294Sstas } 631233294Sstas ps.want_blank = true; 632233294Sstas break; 633178825Sdfr 63455682Smarkm case postop: /* got a trailing ++ or -- */ 635233294Sstas *e_code++ = token[0]; 636233294Sstas *e_code++ = token[1]; 637233294Sstas ps.want_blank = true; 638233294Sstas break; 639233294Sstas 640233294Sstas case question: /* got a ? */ 641233294Sstas squest++; /* this will be used when a later colon 64290926Snectar * appears so we can distinguish the 64372445Sassar * <c>?<n>:<n> construct */ 644178825Sdfr if (ps.want_blank) 645233294Sstas *e_code++ = ' '; 646233294Sstas *e_code++ = '?'; 647233294Sstas ps.want_blank = true; 64890926Snectar break; 64972445Sassar 650178825Sdfr case casestmt: /* got word 'case' or 'default' */ 65190926Snectar scase = true; /* so we can process the later colon properly */ 65255682Smarkm goto copy_id; 653178825Sdfr 654178825Sdfr case colon: /* got a ':' */ 655178825Sdfr if (squest > 0) { /* it is part of the <c>?<n>: <n> construct */ 656178825Sdfr --squest; 65790926Snectar if (ps.want_blank) 65855682Smarkm *e_code++ = ' '; 659178825Sdfr *e_code++ = ':'; 660178825Sdfr ps.want_blank = true; 661178825Sdfr break; 662178825Sdfr } 66390926Snectar if (ps.in_decl) { 66472445Sassar *e_code++ = ':'; 665178825Sdfr ps.want_blank = false; 66690926Snectar break; 66755682Smarkm } 668178825Sdfr ps.in_stmt = false; /* seeing a label does not imply we are in a 66990926Snectar * stmt */ 67090926Snectar for (t_ptr = s_code; *t_ptr; ++t_ptr) 671142403Snectar *e_lab++ = *t_ptr; /* turn everything so far into a label */ 67290926Snectar e_code = s_code; 67390926Snectar *e_lab++ = ':'; 67490926Snectar *e_lab++ = ' '; 67590926Snectar *e_lab = '\0'; 676233294Sstas 677233294Sstas force_nl = ps.pcase = scase; /* ps.pcase will be used by 678233294Sstas * dump_line to decide how to 679233294Sstas * indent the label. force_nl 680233294Sstas * will force a case n: to be 681233294Sstas * on a line by itself */ 682233294Sstas scase = false; 683233294Sstas ps.want_blank = false; 684233294Sstas break; 685233294Sstas 686233294Sstas case semicolon: /* got a ';' */ 687233294Sstas ps.in_or_st = false;/* we are not in an initialization or 688233294Sstas * structure declaration */ 689233294Sstas scase = false; /* these will only need resetting in a error */ 690233294Sstas squest = 0; 69172445Sassar if (ps.last_token == rparen && rparen_count == 0) 692233294Sstas ps.in_parameter_declaration = 0; 693233294Sstas ps.cast_mask = 0; 694233294Sstas ps.sizeof_mask = 0; 695233294Sstas ps.block_init = 0; 696233294Sstas ps.block_init_level = 0; 69790926Snectar ps.just_saw_decl--; 69872445Sassar 699233294Sstas if (ps.in_decl && s_code == e_code && !ps.block_init) 700233294Sstas while ((e_code - s_code) < (dec_ind - 1)) { 701233294Sstas CHECK_SIZE_CODE; 702233294Sstas *e_code++ = ' '; 703233294Sstas } 70490926Snectar 70572445Sassar ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level 706233294Sstas * structure declaration, we 707233294Sstas * arent any more */ 708233294Sstas 709233294Sstas if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) { 710233294Sstas 711102644Snectar /* 712102644Snectar * This should be true iff there were unbalanced parens in the 713102644Snectar * stmt. It is a bit complicated, because the semicolon might 714102644Snectar * be in a for stmt 715102644Snectar */ 716102644Snectar diag2(1, "Unbalanced parens"); 717233294Sstas ps.p_l_follow = 0; 71890926Snectar if (sp_sw) { /* this is a check for a if, while, etc. with 719178825Sdfr * unbalanced parens */ 720233294Sstas sp_sw = false; 721233294Sstas parse(hd_type); /* dont lose the if, or whatever */ 722233294Sstas } 723233294Sstas } 724233294Sstas *e_code++ = ';'; 725233294Sstas ps.want_blank = true; 726233294Sstas ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the 727233294Sstas * middle of a stmt */ 728233294Sstas 729233294Sstas if (!sp_sw) { /* if not if for (;;) */ 730233294Sstas parse(semicolon); /* let parser know about end of stmt */ 731233294Sstas force_nl = true;/* force newline after a end of stmt */ 732233294Sstas } 733233294Sstas break; 734233294Sstas 735233294Sstas case lbrace: /* got a '{' */ 73655682Smarkm ps.in_stmt = false; /* dont indent the {} */ 737233294Sstas if (!ps.block_init) 738233294Sstas force_nl = true;/* force other stuff on same line as '{' onto 739233294Sstas * new line */ 740233294Sstas else if (ps.block_init_level <= 0) 741233294Sstas ps.block_init_level = 1; 742233294Sstas else 743233294Sstas ps.block_init_level++; 74455682Smarkm 74590926Snectar if (s_code != e_code && !ps.block_init) { 746233294Sstas if (!btype_2) { 747233294Sstas dump_line(); 748233294Sstas ps.want_blank = false; 749233294Sstas } 750233294Sstas else if (ps.in_parameter_declaration && !ps.in_or_st) { 751233294Sstas ps.i_l_follow = 0; 752233294Sstas dump_line(); 753233294Sstas ps.want_blank = false; 754233294Sstas } 755233294Sstas } 756233294Sstas if (ps.in_parameter_declaration) 757233294Sstas prefix_blankline_requested = 0; 758233294Sstas 759233294Sstas if (ps.p_l_follow > 0) { /* check for preceding unbalanced 760233294Sstas * parens */ 761233294Sstas diag2(1, "Unbalanced parens"); 762233294Sstas ps.p_l_follow = 0; 763233294Sstas if (sp_sw) { /* check for unclosed if, for, etc. */ 764233294Sstas sp_sw = false; 765233294Sstas parse(hd_type); 766233294Sstas ps.ind_level = ps.i_l_follow; 767233294Sstas } 768233294Sstas } 769233294Sstas if (s_code == e_code) 770233294Sstas ps.ind_stmt = false; /* dont put extra indentation on line 771233294Sstas * with '{' */ 772233294Sstas if (ps.in_decl && ps.in_or_st) { /* this is either a structure 773233294Sstas * declaration or an init */ 77455682Smarkm di_stack[ps.dec_nest++] = dec_ind; 775233294Sstas /* ? dec_ind = 0; */ 776233294Sstas } 777233294Sstas else { 778233294Sstas ps.decl_on_line = false; /* we cant be in the middle of 779233294Sstas * a declaration, so dont do 780233294Sstas * special indentation of 78155682Smarkm * comments */ 782233294Sstas if (blanklines_after_declarations_at_proctop 783233294Sstas && ps.in_parameter_declaration) 784233294Sstas postfix_blankline_requested = 1; 785233294Sstas ps.in_parameter_declaration = 0; 786233294Sstas } 787233294Sstas dec_ind = 0; 788233294Sstas parse(lbrace); /* let parser know about this */ 789233294Sstas if (ps.want_blank) /* put a blank before '{' if '{' is not at 790233294Sstas * start of line */ 791233294Sstas *e_code++ = ' '; 792233294Sstas ps.want_blank = false; 793233294Sstas *e_code++ = '{'; 79472445Sassar ps.just_saw_decl = 0; 795102644Snectar break; 79672445Sassar 79772445Sassar case rbrace: /* got a '}' */ 79872445Sassar if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be 799233294Sstas * omitted in 800233294Sstas * declarations */ 801102644Snectar parse(semicolon); 802142403Snectar if (ps.p_l_follow) {/* check for unclosed if, for, else. */ 80355682Smarkm diag2(1, "Unbalanced parens"); 80472445Sassar ps.p_l_follow = 0; 80572445Sassar sp_sw = false; 806233294Sstas } 80755682Smarkm ps.just_saw_decl = 0; 808102644Snectar ps.block_init_level--; 80972445Sassar if (s_code != e_code && !ps.block_init) { /* '}' must be first on 81072445Sassar * line */ 81172445Sassar if (verbose) 812233294Sstas diag2(0, "Line broken"); 813233294Sstas dump_line(); 814233294Sstas } 815233294Sstas *e_code++ = '}'; 816178825Sdfr ps.want_blank = true; 817233294Sstas ps.in_stmt = ps.ind_stmt = false; 818233294Sstas if (ps.dec_nest > 0) { /* we are in multi-level structure 819233294Sstas * declaration */ 820233294Sstas dec_ind = di_stack[--ps.dec_nest]; 821233294Sstas if (ps.dec_nest == 0 && !ps.in_parameter_declaration) 822233294Sstas ps.just_saw_decl = 2; 823233294Sstas ps.in_decl = true; 824178825Sdfr } 825127808Snectar prefix_blankline_requested = 0; 826127808Snectar parse(rbrace); /* let parser know about this */ 827127808Snectar ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead 828127808Snectar && ps.il[ps.tos] >= ps.ind_level; 829127808Snectar if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0) 830127808Snectar postfix_blankline_requested = 1; 831127808Snectar break; 832233294Sstas 833233294Sstas case swstmt: /* got keyword "switch" */ 834233294Sstas sp_sw = true; 835127808Snectar hd_type = swstmt; /* keep this for when we have seen the 836233294Sstas * expression */ 837127808Snectar goto copy_id; /* go move the token into buffer */ 83878527Sassar 839102644Snectar case sp_paren: /* token is if, while, for */ 840233294Sstas sp_sw = true; /* the interesting stuff is done after the 841233294Sstas * expression is scanned */ 84278527Sassar hd_type = (*token == 'i' ? ifstmt : 84355682Smarkm (*token == 'w' ? whilestmt : forstmt)); 844127808Snectar 84555682Smarkm /* 84655682Smarkm * remember the type of header for later use by parser 847233294Sstas */ 848233294Sstas goto copy_id; /* copy the token into line */ 849233294Sstas 850233294Sstas case sp_nparen: /* got else, do */ 851233294Sstas ps.in_stmt = false; 852233294Sstas if (*token == 'e') { 853233294Sstas if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) { 854233294Sstas if (verbose) 855233294Sstas diag2(0, "Line broken"); 856233294Sstas dump_line();/* make sure this starts a line */ 857233294Sstas ps.want_blank = false; 858233294Sstas } 859233294Sstas force_nl = true;/* also, following stuff must go onto new line */ 860178825Sdfr last_else = 1; 861178825Sdfr parse(elselit); 862178825Sdfr } 863178825Sdfr else { 864178825Sdfr if (e_code != s_code) { /* make sure this starts a line */ 865178825Sdfr if (verbose) 866178825Sdfr diag2(0, "Line broken"); 867178825Sdfr dump_line(); 868178825Sdfr ps.want_blank = false; 869178825Sdfr } 870178825Sdfr force_nl = true;/* also, following stuff must go onto new line */ 871178825Sdfr last_else = 0; 872102644Snectar parse(dolit); 87355682Smarkm } 874178825Sdfr goto copy_id; /* move the token into line */ 875233294Sstas 876233294Sstas case decl: /* we have a declaration type (int, register, 877233294Sstas * etc.) */ 878102644Snectar parse(decl); /* let parser worry about indentation */ 879233294Sstas if (ps.last_token == rparen && ps.tos <= 1) { 880233294Sstas ps.in_parameter_declaration = 1; 881102644Snectar if (s_code != e_code) { 882233294Sstas dump_line(); 88355682Smarkm ps.want_blank = 0; 884233294Sstas } 885233294Sstas } 88672445Sassar if (ps.in_parameter_declaration && ps.indent_parameters && ps.dec_nest == 0) { 88755682Smarkm ps.ind_level = ps.i_l_follow = 1; 88855682Smarkm ps.ind_stmt = 0; 88990926Snectar } 890127808Snectar ps.in_or_st = true; /* this might be a structure or initialization 89190926Snectar * declaration */ 89255682Smarkm ps.in_decl = ps.decl_on_line = true; 89355682Smarkm if ( /* !ps.in_or_st && */ ps.dec_nest <= 0) 89455682Smarkm ps.just_saw_decl = 2; 89590926Snectar prefix_blankline_requested = 0; 89690926Snectar for (i = 0; token[i++];); /* get length of token */ 897233294Sstas 898178825Sdfr /* 899142403Snectar * dec_ind = e_code - s_code + (ps.decl_indent>i ? ps.decl_indent 90090926Snectar * : i); 90155682Smarkm */ 90255682Smarkm dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i; 90390926Snectar goto copy_id; 90455682Smarkm 90555682Smarkm case ident: /* got an identifier or constant */ 90655682Smarkm if (ps.in_decl) { /* if we are in a declaration, we must indent 90790926Snectar * identifier */ 90890926Snectar if (ps.want_blank) 90955682Smarkm *e_code++ = ' '; 91090926Snectar ps.want_blank = false; 911127808Snectar if (is_procname == 0 || !procnames_start_line) { 91290926Snectar if (!ps.block_init) { 91390926Snectar if (troff && !ps.dumped_decl_indent) { 91455682Smarkm sprintf(e_code, "\n.De %dp+\200p\n", dec_ind * 7); 91555682Smarkm ps.dumped_decl_indent = 1; 91655682Smarkm e_code += strlen(e_code); 917178825Sdfr } else { 91855682Smarkm while ((e_code - s_code) < dec_ind) { 91955682Smarkm CHECK_SIZE_CODE; 920178825Sdfr *e_code++ = ' '; 921233294Sstas } 92255682Smarkm } 92355682Smarkm } 92490926Snectar } else { 92590926Snectar if (dec_ind && s_code != e_code) 92690926Snectar dump_line(); 92755682Smarkm dec_ind = 0; 928178825Sdfr ps.want_blank = false; 929178825Sdfr } 93055682Smarkm } 93190926Snectar else if (sp_sw && ps.p_l_follow == 0) { 932233294Sstas sp_sw = false; 933127808Snectar force_nl = true; 93490926Snectar ps.last_u_d = true; 935178825Sdfr ps.in_stmt = false; 93655682Smarkm parse(hd_type); 93790926Snectar } 93855682Smarkm copy_id: 93990926Snectar if (ps.want_blank) 94055682Smarkm *e_code++ = ' '; 941142403Snectar if (troff && ps.its_a_keyword) { 942142403Snectar e_code = chfont(&bodyf, &keywordf, e_code); 943233294Sstas for (t_ptr = token; *t_ptr; ++t_ptr) { 944233294Sstas CHECK_SIZE_CODE; 94590926Snectar *e_code++ = keywordf.allcaps && islower(*t_ptr) 94655682Smarkm ? toupper(*t_ptr) : *t_ptr; 94790926Snectar } 94890926Snectar e_code = chfont(&keywordf, &bodyf, e_code); 949120945Snectar } 950120945Snectar else 951120945Snectar for (t_ptr = token; *t_ptr; ++t_ptr) { 952178825Sdfr CHECK_SIZE_CODE; 953178825Sdfr *e_code++ = *t_ptr; 954233294Sstas } 955233294Sstas ps.want_blank = true; 956178825Sdfr break; 95790926Snectar 95890926Snectar case period: /* treat a period kind of like a binary 959178825Sdfr * operation */ 960178825Sdfr *e_code++ = '.'; /* move the period into line */ 961233294Sstas ps.want_blank = false; /* dont put a blank after a period */ 962233294Sstas break; 96390926Snectar 96490926Snectar case comma: 965233294Sstas ps.want_blank = (s_code != e_code); /* only put blank after comma 96690926Snectar * if comma does not start the 967233294Sstas * line */ 968233294Sstas if (ps.in_decl && is_procname == 0 && !ps.block_init) 969178825Sdfr while ((e_code - s_code) < (dec_ind - 1)) { 970178825Sdfr CHECK_SIZE_CODE; 971233294Sstas *e_code++ = ' '; 972233294Sstas } 973178825Sdfr 974178825Sdfr *e_code++ = ','; 975233294Sstas if (ps.p_l_follow == 0) { 976233294Sstas if (ps.block_init_level <= 0) 97790926Snectar ps.block_init = 0; 97890926Snectar if (break_comma && (!ps.leave_comma || compute_code_target() + (e_code - s_code) > max_col - 8)) 97955682Smarkm force_nl = true; 980233294Sstas } 981127808Snectar break; 98290926Snectar 98355682Smarkm case preesc: /* got the character '#' */ 98490926Snectar if ((s_com != e_com) || 98555682Smarkm (s_lab != e_lab) || 98690926Snectar (s_code != e_code)) 98790926Snectar dump_line(); 98890926Snectar *e_lab++ = '#'; /* move whole line to 'label' buffer */ 989127808Snectar { 990127808Snectar int in_comment = 0; 991127808Snectar int com_start = 0; 992127808Snectar char quote = 0; 993127808Snectar int com_end = 0; 994127808Snectar 995127808Snectar while (*buf_ptr == ' ' || *buf_ptr == '\t') { 996127808Snectar buf_ptr++; 997178825Sdfr if (buf_ptr >= buf_end) 998178825Sdfr fill_buffer(); 999178825Sdfr } 1000178825Sdfr while (*buf_ptr != '\n' || (in_comment && !had_eof)) { 1001233294Sstas CHECK_SIZE_LAB; 100290926Snectar *e_lab = *buf_ptr++; 1003233294Sstas if (buf_ptr >= buf_end) 1004233294Sstas fill_buffer(); 100590926Snectar switch (*e_lab++) { 1006127808Snectar case BACKSLASH: 1007178825Sdfr if (troff) 1008178825Sdfr *e_lab++ = BACKSLASH; 1009178825Sdfr if (!in_comment) { 1010178825Sdfr *e_lab++ = *buf_ptr++; 1011178825Sdfr if (buf_ptr >= buf_end) 1012178825Sdfr fill_buffer(); 1013178825Sdfr } 1014178825Sdfr break; 1015233294Sstas case '/': 1016233294Sstas if (*buf_ptr == '*' && !in_comment && !quote) { 1017233294Sstas in_comment = 1; 1018233294Sstas *e_lab++ = *buf_ptr++; 1019233294Sstas com_start = e_lab - s_lab - 2; 1020233294Sstas } 1021233294Sstas break; 1022233294Sstas case '"': 102390926Snectar if (quote == '"') 102490926Snectar quote = 0; 102555682Smarkm break; 102655682Smarkm case '\'': 102755682Smarkm if (quote == '\'') 102855682Smarkm quote = 0; 102955682Smarkm break; 103072445Sassar case '*': 103172445Sassar if (*buf_ptr == '/' && in_comment) { 103272445Sassar in_comment = 0; 103372445Sassar *e_lab++ = *buf_ptr++; 103455682Smarkm com_end = e_lab - s_lab; 103555682Smarkm } 103655682Smarkm break; 1037178825Sdfr } 1038178825Sdfr } 103955682Smarkm 104055682Smarkm while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 104155682Smarkm e_lab--; 104255682Smarkm if (e_lab - s_lab == com_end && bp_save == 0) { /* comment on 104355682Smarkm * preprocessor line */ 104455682Smarkm if (sc_end == 0) /* if this is the first comment, we 104572445Sassar * must set up the buffer */ 104672445Sassar sc_end = &(save_com[0]); 104755682Smarkm else { 1048178825Sdfr *sc_end++ = '\n'; /* add newline between 1049178825Sdfr * comments */ 1050178825Sdfr *sc_end++ = ' '; 1051178825Sdfr --line_no; 1052178825Sdfr } 1053178825Sdfr bcopy(s_lab + com_start, sc_end, com_end - com_start); 1054178825Sdfr sc_end += com_end - com_start; 1055178825Sdfr if (sc_end >= &save_com[sc_size]) 1056178825Sdfr abort(); 1057178825Sdfr e_lab = s_lab + com_start; 1058178825Sdfr while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 105955682Smarkm e_lab--; 106055682Smarkm bp_save = buf_ptr; /* save current input buffer */ 106155682Smarkm be_save = buf_end; 1062102644Snectar buf_ptr = save_com; /* fix so that subsequent calls to 1063102644Snectar * lexi will take tokens out of 1064178825Sdfr * save_com */ 1065178825Sdfr *sc_end++ = ' '; /* add trailing blank, just in case */ 1066102644Snectar buf_end = sc_end; 1067102644Snectar sc_end = 0; 1068102644Snectar } 1069102644Snectar *e_lab = '\0'; /* null terminate line */ 1070102644Snectar ps.pcase = false; 1071102644Snectar } 1072178825Sdfr 1073102644Snectar if (strncmp(s_lab, "#if", 3) == 0) { 1074102644Snectar if (blanklines_around_conditional_compilation) { 1075102644Snectar int c; 1076102644Snectar prefix_blankline_requested++; 1077102644Snectar while ((c = getc(input)) == '\n'); 1078102644Snectar ungetc(c, input); 1079102644Snectar } 1080102644Snectar if ((size_t)ifdef_level < sizeof(state_stack)/sizeof(state_stack[0])) { 1081102644Snectar match_state[ifdef_level].tos = -1; 1082102644Snectar state_stack[ifdef_level++] = ps; 1083102644Snectar } 1084102644Snectar else 1085102644Snectar diag2(1, "#if stack overflow"); 1086102644Snectar } 1087102644Snectar else if (strncmp(s_lab, "#else", 5) == 0) 1088178825Sdfr if (ifdef_level <= 0) 1089102644Snectar diag2(1, "Unmatched #else"); 1090102644Snectar else { 1091102644Snectar match_state[ifdef_level - 1] = ps; 1092102644Snectar ps = state_stack[ifdef_level - 1]; 1093233294Sstas } 1094233294Sstas else if (strncmp(s_lab, "#endif", 6) == 0) { 1095233294Sstas if (ifdef_level <= 0) 109655682Smarkm diag2(1, "Unmatched #endif"); 109755682Smarkm else { 109855682Smarkm ifdef_level--; 109955682Smarkm 110055682Smarkm#ifdef undef 110155682Smarkm /* 110255682Smarkm * This match needs to be more intelligent before the 110355682Smarkm * message is useful 110455682Smarkm */ 110555682Smarkm if (match_state[ifdef_level].tos >= 0 110655682Smarkm && bcmp(&ps, &match_state[ifdef_level], sizeof ps)) 110755682Smarkm diag2(0, "Syntactically inconsistant #ifdef alternatives."); 110855682Smarkm#endif 110955682Smarkm } 111055682Smarkm if (blanklines_around_conditional_compilation) { 111155682Smarkm postfix_blankline_requested++; 111255682Smarkm n_real_blanklines = 0; 111355682Smarkm } 111455682Smarkm } 111555682Smarkm break; /* subsequent processing of the newline 111655682Smarkm * character will cause the line to be printed */ 111755682Smarkm 111855682Smarkm case comment: /* we have gotten a / followed by * this is a biggie */ 111955682Smarkm if (flushed_nl) { /* we should force a broken line here */ 112055682Smarkm flushed_nl = false; 112155682Smarkm dump_line(); 112255682Smarkm ps.want_blank = false; /* dont insert blank at line start */ 112355682Smarkm force_nl = false; 112455682Smarkm } 112555682Smarkm pr_comment(); 112655682Smarkm break; 112755682Smarkm } /* end of big switch stmt */ 112855682Smarkm 112955682Smarkm *e_code = '\0'; /* make sure code section is null terminated */ 113055682Smarkm if (type_code != comment && type_code != newline && type_code != preesc) 113155682Smarkm ps.last_token = type_code; 113255682Smarkm } /* end of main while (1) loop */ 113355682Smarkm} 113455682Smarkm 113555682Smarkm/* 113655682Smarkm * copy input file to backup file if in_name is /blah/blah/blah/file, then 113755682Smarkm * backup file will be ".Bfile" then make the backup file the input and 113855682Smarkm * original input file the output 113955682Smarkm */ 114055682Smarkmstatic void 114155682Smarkmbakcopy(void) 114255682Smarkm{ 114355682Smarkm int n, 114455682Smarkm bakchn; 114555682Smarkm char buff[8 * 1024]; 114655682Smarkm const char *p; 114755682Smarkm 114855682Smarkm /* construct file name .Bfile */ 114955682Smarkm for (p = in_name; *p; p++); /* skip to end of string */ 115055682Smarkm while (p > in_name && *p != '/') /* find last '/' */ 115155682Smarkm p--; 115255682Smarkm if (*p == '/') 115355682Smarkm p++; 115455682Smarkm sprintf(bakfile, "%s.BAK", p); 115555682Smarkm 115655682Smarkm /* copy in_name to backup file */ 115755682Smarkm bakchn = creat(bakfile, 0600); 115855682Smarkm if (bakchn < 0) 115955682Smarkm err(1, "%s", bakfile); 116072445Sassar while ((n = read(fileno(input), buff, sizeof buff)) != 0) 1161178825Sdfr if (write(bakchn, buff, n) != n) 116255682Smarkm err(1, "%s", bakfile); 1163178825Sdfr if (n < 0) 1164178825Sdfr err(1, "%s", in_name); 1165178825Sdfr close(bakchn); 1166120945Snectar fclose(input); 1167178825Sdfr 116855682Smarkm /* re-open backup file as the input file */ 116955682Smarkm input = fopen(bakfile, "r"); 117055682Smarkm if (input == 0) 117155682Smarkm err(1, "%s", bakfile); 117255682Smarkm /* now the original input file will be the output */ 117355682Smarkm output = fopen(in_name, "w"); 1174178825Sdfr if (output == 0) { 1175178825Sdfr unlink(bakfile); 1176178825Sdfr err(1, "%s", in_name); 1177178825Sdfr } 1178178825Sdfr} 1179178825Sdfr