11590Srgrimes/* 21590Srgrimes * Copyright (c) 1985 Sun Microsystems, Inc. 31590Srgrimes * Copyright (c) 1976 Board of Trustees of the University of Illinois. 41590Srgrimes * Copyright (c) 1980, 1993 51590Srgrimes * The Regents of the University of California. All rights reserved. 61590Srgrimes * 71590Srgrimes * Redistribution and use in source and binary forms, with or without 81590Srgrimes * modification, are permitted provided that the following conditions 91590Srgrimes * are met: 101590Srgrimes * 1. Redistributions of source code must retain the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer. 121590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 131590Srgrimes * notice, this list of conditions and the following disclaimer in the 141590Srgrimes * documentation and/or other materials provided with the distribution. 151590Srgrimes * 3. All advertising materials mentioning features or use of this software 161590Srgrimes * must display the following acknowledgement: 171590Srgrimes * This product includes software developed by the University of 181590Srgrimes * California, Berkeley and its contributors. 191590Srgrimes * 4. Neither the name of the University nor the names of its contributors 201590Srgrimes * may be used to endorse or promote products derived from this software 211590Srgrimes * without specific prior written permission. 221590Srgrimes * 231590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 241590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 251590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 261590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 271590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 281590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 291590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 301590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 311590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 321590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 331590Srgrimes * SUCH DAMAGE. 341590Srgrimes */ 351590Srgrimes 361590Srgrimes#ifndef lint 3727419Scharnierstatic const char copyright[] = 381590Srgrimes"@(#) Copyright (c) 1985 Sun Microsystems, Inc.\n\ 391590Srgrimes@(#) Copyright (c) 1976 Board of Trustees of the University of Illinois.\n\ 401590Srgrimes@(#) Copyright (c) 1980, 1993\n\ 411590Srgrimes The Regents of the University of California. All rights reserved.\n"; 421590Srgrimes#endif /* not lint */ 431590Srgrimes 44116390Scharnier#if 0 451590Srgrimes#ifndef lint 461590Srgrimesstatic char sccsid[] = "@(#)indent.c 5.17 (Berkeley) 6/7/93"; 47116390Scharnier#endif /* not lint */ 4827419Scharnier#endif 49116390Scharnier 5099112Sobrien#include <sys/cdefs.h> 5199112Sobrien__FBSDID("$FreeBSD$"); 521590Srgrimes 531590Srgrimes#include <sys/param.h> 5427419Scharnier#include <err.h> 551590Srgrimes#include <fcntl.h> 561590Srgrimes#include <unistd.h> 571590Srgrimes#include <stdio.h> 581590Srgrimes#include <stdlib.h> 591590Srgrimes#include <string.h> 6085632Sschweikh#include <ctype.h> 611590Srgrimes#include "indent_globs.h" 621590Srgrimes#include "indent_codes.h" 6385632Sschweikh#include "indent.h" 641590Srgrimes 6585632Sschweikhstatic void bakcopy(void); 6685632Sschweikh 6793440Sdwmaloneconst char *in_name = "Standard Input"; /* will always point to name of input 681590Srgrimes * file */ 6993440Sdwmaloneconst char *out_name = "Standard Output"; /* will always point to name 701590Srgrimes * of output file */ 711590Srgrimeschar bakfile[MAXPATHLEN] = ""; 721590Srgrimes 7385632Sschweikhint 7485632Sschweikhmain(int argc, char **argv) 751590Srgrimes{ 761590Srgrimes 771590Srgrimes int dec_ind; /* current indentation for declarations */ 781590Srgrimes int di_stack[20]; /* a stack of structure indentation levels */ 791590Srgrimes int flushed_nl; /* used when buffering up comments to remember 801590Srgrimes * that a newline was passed over */ 811590Srgrimes int force_nl; /* when true, code must be broken */ 8285632Sschweikh int hd_type = 0; /* used to store type of stmt for if (...), 831590Srgrimes * for (...), etc */ 84131184Sschweikh int i; /* local loop counter */ 851590Srgrimes int scase; /* set to true when we see a case, so we will 861590Srgrimes * know what to do with the following colon */ 87105244Scharnier int sp_sw; /* when true, we are in the expression of 881590Srgrimes * if(...), while(...), etc. */ 891590Srgrimes int squest; /* when this is positive, we have seen a ? 901590Srgrimes * without the matching : in a <c>?<s>:<s> 911590Srgrimes * construct */ 9293440Sdwmalone const char *t_ptr; /* used for copying tokens */ 93131184Sschweikh int tabs_to_var; /* true if using tabs to indent to var name */ 941590Srgrimes int type_code; /* the type of token, returned by lexi */ 951590Srgrimes 961590Srgrimes int last_else = 0; /* true iff last keyword was an else */ 971590Srgrimes 981590Srgrimes 991590Srgrimes /*-----------------------------------------------*\ 1001590Srgrimes | INITIALIZATION | 1011590Srgrimes \*-----------------------------------------------*/ 1021590Srgrimes 103116390Scharnier found_err = 0; 1041590Srgrimes 1051590Srgrimes ps.p_stack[0] = stmt; /* this is the parser's stack */ 1061590Srgrimes ps.last_nl = true; /* this is true if the last thing scanned was 1071590Srgrimes * a newline */ 1081590Srgrimes ps.last_token = semicolon; 1091590Srgrimes combuf = (char *) malloc(bufsize); 110116390Scharnier if (combuf == NULL) 111116390Scharnier err(1, NULL); 1121590Srgrimes labbuf = (char *) malloc(bufsize); 113116390Scharnier if (labbuf == NULL) 114116390Scharnier err(1, NULL); 1151590Srgrimes codebuf = (char *) malloc(bufsize); 116116390Scharnier if (codebuf == NULL) 117116390Scharnier err(1, NULL); 1181590Srgrimes tokenbuf = (char *) malloc(bufsize); 119116390Scharnier if (tokenbuf == NULL) 120116390Scharnier err(1, NULL); 1211590Srgrimes l_com = combuf + bufsize - 5; 1221590Srgrimes l_lab = labbuf + bufsize - 5; 1231590Srgrimes l_code = codebuf + bufsize - 5; 1241590Srgrimes l_token = tokenbuf + bufsize - 5; 1251590Srgrimes combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and 1261590Srgrimes * comment buffers */ 1271590Srgrimes combuf[1] = codebuf[1] = labbuf[1] = '\0'; 1281590Srgrimes ps.else_if = 1; /* Default else-if special processing to on */ 1291590Srgrimes s_lab = e_lab = labbuf + 1; 1301590Srgrimes s_code = e_code = codebuf + 1; 1311590Srgrimes s_com = e_com = combuf + 1; 1321590Srgrimes s_token = e_token = tokenbuf + 1; 1331590Srgrimes 1341590Srgrimes in_buffer = (char *) malloc(10); 135116390Scharnier if (in_buffer == NULL) 136116390Scharnier err(1, NULL); 1371590Srgrimes in_buffer_limit = in_buffer + 8; 1381590Srgrimes buf_ptr = buf_end = in_buffer; 1391590Srgrimes line_no = 1; 1401590Srgrimes had_eof = ps.in_decl = ps.decl_on_line = break_comma = false; 1411590Srgrimes sp_sw = force_nl = false; 1421590Srgrimes ps.in_or_st = false; 1431590Srgrimes ps.bl_line = true; 1441590Srgrimes dec_ind = 0; 1451590Srgrimes di_stack[ps.dec_nest = 0] = 0; 1461590Srgrimes ps.want_blank = ps.in_stmt = ps.ind_stmt = false; 1471590Srgrimes 1481590Srgrimes scase = ps.pcase = false; 1491590Srgrimes squest = 0; 1501590Srgrimes sc_end = 0; 1511590Srgrimes bp_save = 0; 1521590Srgrimes be_save = 0; 1531590Srgrimes 1541590Srgrimes output = 0; 155162264Scharnier tabs_to_var = 0; 1561590Srgrimes 1571590Srgrimes /*--------------------------------------------------*\ 1581590Srgrimes | COMMAND LINE SCAN | 1591590Srgrimes \*--------------------------------------------------*/ 1601590Srgrimes 1611590Srgrimes#ifdef undef 1621590Srgrimes max_col = 78; /* -l78 */ 1631590Srgrimes lineup_to_parens = 1; /* -lp */ 1641590Srgrimes ps.ljust_decl = 0; /* -ndj */ 1651590Srgrimes ps.com_ind = 33; /* -c33 */ 1661590Srgrimes star_comment_cont = 1; /* -sc */ 1671590Srgrimes ps.ind_size = 8; /* -i8 */ 1681590Srgrimes verbose = 0; 1691590Srgrimes ps.decl_indent = 16; /* -di16 */ 170125633Sbde ps.local_decl_indent = -1; /* if this is not set to some nonnegative value 171125633Sbde * by an arg, we will set this equal to 172125633Sbde * ps.decl_ind */ 1731590Srgrimes ps.indent_parameters = 1; /* -ip */ 1741590Srgrimes ps.decl_com_ind = 0; /* if this is not set to some positive value 1751590Srgrimes * by an arg, we will set this equal to 1761590Srgrimes * ps.com_ind */ 1771590Srgrimes btype_2 = 1; /* -br */ 1781590Srgrimes cuddle_else = 1; /* -ce */ 1791590Srgrimes ps.unindent_displace = 0; /* -d0 */ 1801590Srgrimes ps.case_indent = 0; /* -cli0 */ 18169795Sobrien format_block_comments = 1; /* -fcb */ 1821590Srgrimes format_col1_comments = 1; /* -fc1 */ 1831590Srgrimes procnames_start_line = 1; /* -psl */ 1841590Srgrimes proc_calls_space = 0; /* -npcs */ 1851590Srgrimes comment_delimiter_on_blankline = 1; /* -cdb */ 1861590Srgrimes ps.leave_comma = 1; /* -nbc */ 1871590Srgrimes#endif 1881590Srgrimes 1891590Srgrimes for (i = 1; i < argc; ++i) 1901590Srgrimes if (strcmp(argv[i], "-npro") == 0) 1911590Srgrimes break; 1921590Srgrimes set_defaults(); 1931590Srgrimes if (i >= argc) 1941590Srgrimes set_profile(); 1951590Srgrimes 1961590Srgrimes for (i = 1; i < argc; ++i) { 1971590Srgrimes 1981590Srgrimes /* 1991590Srgrimes * look thru args (if any) for changes to defaults 2001590Srgrimes */ 2011590Srgrimes if (argv[i][0] != '-') {/* no flag on parameter */ 202211132Skevlo if (input == NULL) { /* we must have the input file */ 2031590Srgrimes in_name = argv[i]; /* remember name of input file */ 2041590Srgrimes input = fopen(in_name, "r"); 205211132Skevlo if (input == NULL) /* check for open error */ 20662894Skris err(1, "%s", in_name); 2071590Srgrimes continue; 2081590Srgrimes } 209211132Skevlo else if (output == NULL) { /* we have the output file */ 2101590Srgrimes out_name = argv[i]; /* remember name of output file */ 2111590Srgrimes if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite 2121590Srgrimes * the file */ 21327419Scharnier errx(1, "input and output files must be different"); 2141590Srgrimes } 2151590Srgrimes output = fopen(out_name, "w"); 216211132Skevlo if (output == NULL) /* check for create error */ 21762894Skris err(1, "%s", out_name); 2181590Srgrimes continue; 2191590Srgrimes } 22027419Scharnier errx(1, "unknown parameter: %s", argv[i]); 2211590Srgrimes } 2221590Srgrimes else 2231590Srgrimes set_option(argv[i]); 2241590Srgrimes } /* end of for */ 225211132Skevlo if (input == NULL) 22640502Sthepish input = stdin; 227211132Skevlo if (output == NULL) { 22840502Sthepish if (troff || input == stdin) 2291590Srgrimes output = stdout; 2301590Srgrimes else { 2311590Srgrimes out_name = in_name; 2321590Srgrimes bakcopy(); 2331590Srgrimes } 23448566Sbillf } 2351590Srgrimes if (ps.com_ind <= 1) 2361590Srgrimes ps.com_ind = 2; /* dont put normal comments before column 2 */ 2371590Srgrimes if (troff) { 2381590Srgrimes if (bodyf.font[0] == 0) 2391590Srgrimes parsefont(&bodyf, "R"); 2401590Srgrimes if (scomf.font[0] == 0) 2411590Srgrimes parsefont(&scomf, "I"); 2421590Srgrimes if (blkcomf.font[0] == 0) 2431590Srgrimes blkcomf = scomf, blkcomf.size += 2; 2441590Srgrimes if (boxcomf.font[0] == 0) 2451590Srgrimes boxcomf = blkcomf; 2461590Srgrimes if (stringf.font[0] == 0) 2471590Srgrimes parsefont(&stringf, "L"); 2481590Srgrimes if (keywordf.font[0] == 0) 2491590Srgrimes parsefont(&keywordf, "B"); 2501590Srgrimes writefdef(&bodyf, 'B'); 2511590Srgrimes writefdef(&scomf, 'C'); 2521590Srgrimes writefdef(&blkcomf, 'L'); 2531590Srgrimes writefdef(&boxcomf, 'X'); 2541590Srgrimes writefdef(&stringf, 'S'); 2551590Srgrimes writefdef(&keywordf, 'K'); 2561590Srgrimes } 2571590Srgrimes if (block_comment_max_col <= 0) 2581590Srgrimes block_comment_max_col = max_col; 259125633Sbde if (ps.local_decl_indent < 0) /* if not specified by user, set this */ 260125633Sbde ps.local_decl_indent = ps.decl_indent; 2611590Srgrimes if (ps.decl_com_ind <= 0) /* if not specified by user, set this */ 2621590Srgrimes ps.decl_com_ind = ps.ljust_decl ? (ps.com_ind <= 10 ? 2 : ps.com_ind - 8) : ps.com_ind; 2631590Srgrimes if (continuation_indent == 0) 2641590Srgrimes continuation_indent = ps.ind_size; 2651590Srgrimes fill_buffer(); /* get first batch of stuff into input buffer */ 2661590Srgrimes 2671590Srgrimes parse(semicolon); 2681590Srgrimes { 26998771Sjmallett char *p = buf_ptr; 27098771Sjmallett int col = 1; 2711590Srgrimes 2721590Srgrimes while (1) { 2731590Srgrimes if (*p == ' ') 2741590Srgrimes col++; 2751590Srgrimes else if (*p == '\t') 2761590Srgrimes col = ((col - 1) & ~7) + 9; 2771590Srgrimes else 2781590Srgrimes break; 2791590Srgrimes p++; 2801590Srgrimes } 2811590Srgrimes if (col > ps.ind_size) 2821590Srgrimes ps.ind_level = ps.i_l_follow = col / ps.ind_size; 2831590Srgrimes } 2841590Srgrimes if (troff) { 28593440Sdwmalone const char *p = in_name, 2861590Srgrimes *beg = in_name; 2871590Srgrimes 2881590Srgrimes while (*p) 2891590Srgrimes if (*p++ == '/') 2901590Srgrimes beg = p; 2911590Srgrimes fprintf(output, ".Fn \"%s\"\n", beg); 2921590Srgrimes } 2931590Srgrimes /* 2941590Srgrimes * START OF MAIN LOOP 2951590Srgrimes */ 2961590Srgrimes 2971590Srgrimes while (1) { /* this is the main loop. it will go until we 2981590Srgrimes * reach eof */ 2991590Srgrimes int is_procname; 3001590Srgrimes 3011590Srgrimes type_code = lexi(); /* lexi reads one token. The actual 3021590Srgrimes * characters read are stored in "token". lexi 3031590Srgrimes * returns a code indicating the type of token */ 3041590Srgrimes is_procname = ps.procname[0]; 3051590Srgrimes 3061590Srgrimes /* 3071590Srgrimes * The following code moves everything following an if (), while (), 3081590Srgrimes * else, etc. up to the start of the following stmt to a buffer. This 3091590Srgrimes * allows proper handling of both kinds of brace placement. 3101590Srgrimes */ 3111590Srgrimes 3121590Srgrimes flushed_nl = false; 3131590Srgrimes while (ps.search_brace) { /* if we scanned an if(), while(), 3141590Srgrimes * etc., we might need to copy stuff 3151590Srgrimes * into a buffer we must loop, copying 3161590Srgrimes * stuff into save_com, until we find 3171590Srgrimes * the start of the stmt which follows 3181590Srgrimes * the if, or whatever */ 3191590Srgrimes switch (type_code) { 3201590Srgrimes case newline: 3211590Srgrimes ++line_no; 3221590Srgrimes flushed_nl = true; 3231590Srgrimes case form_feed: 3241590Srgrimes break; /* form feeds and newlines found here will be 3251590Srgrimes * ignored */ 3261590Srgrimes 3271590Srgrimes case lbrace: /* this is a brace that starts the compound 3281590Srgrimes * stmt */ 329228992Suqs if (sc_end == 0) { /* ignore buffering if a comment wasn't 3301590Srgrimes * stored up */ 3311590Srgrimes ps.search_brace = false; 3321590Srgrimes goto check_type; 3331590Srgrimes } 3341590Srgrimes if (btype_2) { 3351590Srgrimes save_com[0] = '{'; /* we either want to put the brace 3361590Srgrimes * right after the if */ 3371590Srgrimes goto sw_buffer; /* go to common code to get out of 3381590Srgrimes * this loop */ 3391590Srgrimes } 3401590Srgrimes case comment: /* we have a comment, so we must copy it into 3411590Srgrimes * the buffer */ 3421590Srgrimes if (!flushed_nl || sc_end != 0) { 3431590Srgrimes if (sc_end == 0) { /* if this is the first comment, we 3441590Srgrimes * must set up the buffer */ 3451590Srgrimes save_com[0] = save_com[1] = ' '; 3461590Srgrimes sc_end = &(save_com[2]); 3471590Srgrimes } 3481590Srgrimes else { 3491590Srgrimes *sc_end++ = '\n'; /* add newline between 3501590Srgrimes * comments */ 3511590Srgrimes *sc_end++ = ' '; 3521590Srgrimes --line_no; 3531590Srgrimes } 3541590Srgrimes *sc_end++ = '/'; /* copy in start of comment */ 3551590Srgrimes *sc_end++ = '*'; 3561590Srgrimes 3571590Srgrimes for (;;) { /* loop until we get to the end of the comment */ 3581590Srgrimes *sc_end = *buf_ptr++; 3591590Srgrimes if (buf_ptr >= buf_end) 3601590Srgrimes fill_buffer(); 3611590Srgrimes 3621590Srgrimes if (*sc_end++ == '*' && *buf_ptr == '/') 3631590Srgrimes break; /* we are at end of comment */ 3641590Srgrimes 3651590Srgrimes if (sc_end >= &(save_com[sc_size])) { /* check for temp buffer 3661590Srgrimes * overflow */ 367116390Scharnier diag2(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever"); 3681590Srgrimes fflush(output); 3691590Srgrimes exit(1); 3701590Srgrimes } 3711590Srgrimes } 3721590Srgrimes *sc_end++ = '/'; /* add ending slash */ 3731590Srgrimes if (++buf_ptr >= buf_end) /* get past / in buffer */ 3741590Srgrimes fill_buffer(); 3751590Srgrimes break; 3761590Srgrimes } 377105244Scharnier default: /* it is the start of a normal statement */ 3781590Srgrimes if (flushed_nl) /* if we flushed a newline, make sure it is 3791590Srgrimes * put back */ 3801590Srgrimes force_nl = true; 38185632Sschweikh if ((type_code == sp_paren && *token == 'i' 38285632Sschweikh && last_else && ps.else_if) 38385632Sschweikh || (type_code == sp_nparen && *token == 'e' 38485632Sschweikh && e_code != s_code && e_code[-1] == '}')) 3851590Srgrimes force_nl = false; 3861590Srgrimes 387228992Suqs if (sc_end == 0) { /* ignore buffering if comment wasn't 3881590Srgrimes * saved up */ 3891590Srgrimes ps.search_brace = false; 3901590Srgrimes goto check_type; 3911590Srgrimes } 3921590Srgrimes if (force_nl) { /* if we should insert a nl here, put it into 3931590Srgrimes * the buffer */ 3941590Srgrimes force_nl = false; 3951590Srgrimes --line_no; /* this will be re-increased when the nl is 3961590Srgrimes * read from the buffer */ 3971590Srgrimes *sc_end++ = '\n'; 3981590Srgrimes *sc_end++ = ' '; 3991590Srgrimes if (verbose && !flushed_nl) /* print error msg if the line 4001590Srgrimes * was not already broken */ 40185632Sschweikh diag2(0, "Line broken"); 4021590Srgrimes flushed_nl = false; 4031590Srgrimes } 4041590Srgrimes for (t_ptr = token; *t_ptr; ++t_ptr) 4051590Srgrimes *sc_end++ = *t_ptr; /* copy token into temp buffer */ 4061590Srgrimes ps.procname[0] = 0; 4071590Srgrimes 4081590Srgrimes sw_buffer: 4091590Srgrimes ps.search_brace = false; /* stop looking for start of 4101590Srgrimes * stmt */ 4111590Srgrimes bp_save = buf_ptr; /* save current input buffer */ 4121590Srgrimes be_save = buf_end; 4131590Srgrimes buf_ptr = save_com; /* fix so that subsequent calls to 4141590Srgrimes * lexi will take tokens out of 4151590Srgrimes * save_com */ 4161590Srgrimes *sc_end++ = ' ';/* add trailing blank, just in case */ 4171590Srgrimes buf_end = sc_end; 4181590Srgrimes sc_end = 0; 4191590Srgrimes break; 4201590Srgrimes } /* end of switch */ 4211590Srgrimes if (type_code != 0) /* we must make this check, just in case there 4221590Srgrimes * was an unexpected EOF */ 4231590Srgrimes type_code = lexi(); /* read another token */ 4241590Srgrimes /* if (ps.search_brace) ps.procname[0] = 0; */ 4251590Srgrimes if ((is_procname = ps.procname[0]) && flushed_nl 4261590Srgrimes && !procnames_start_line && ps.in_decl 4271590Srgrimes && type_code == ident) 4281590Srgrimes flushed_nl = 0; 4291590Srgrimes } /* end of while (search_brace) */ 4301590Srgrimes last_else = 0; 4311590Srgrimescheck_type: 4321590Srgrimes if (type_code == 0) { /* we got eof */ 4331590Srgrimes if (s_lab != e_lab || s_code != e_code 4341590Srgrimes || s_com != e_com) /* must dump end of line */ 4351590Srgrimes dump_line(); 4361590Srgrimes if (ps.tos > 1) /* check for balanced braces */ 437116390Scharnier diag2(1, "Stuff missing from end of file"); 4381590Srgrimes 4391590Srgrimes if (verbose) { 4401590Srgrimes printf("There were %d output lines and %d comments\n", 4411590Srgrimes ps.out_lines, ps.out_coms); 4421590Srgrimes printf("(Lines with comments)/(Lines with code): %6.3f\n", 4431590Srgrimes (1.0 * ps.com_lines) / code_lines); 4441590Srgrimes } 4451590Srgrimes fflush(output); 4461590Srgrimes exit(found_err); 4471590Srgrimes } 4481590Srgrimes if ( 4491590Srgrimes (type_code != comment) && 4501590Srgrimes (type_code != newline) && 4511590Srgrimes (type_code != preesc) && 4521590Srgrimes (type_code != form_feed)) { 4531590Srgrimes if (force_nl && 4541590Srgrimes (type_code != semicolon) && 4551590Srgrimes (type_code != lbrace || !btype_2)) { 4561590Srgrimes /* we should force a broken line here */ 4571590Srgrimes if (verbose && !flushed_nl) 45885632Sschweikh diag2(0, "Line broken"); 4591590Srgrimes flushed_nl = false; 4601590Srgrimes dump_line(); 4611590Srgrimes ps.want_blank = false; /* dont insert blank at line start */ 4621590Srgrimes force_nl = false; 4631590Srgrimes } 4641590Srgrimes ps.in_stmt = true; /* turn on flag which causes an extra level of 4651590Srgrimes * indentation. this is turned off by a ; or 4661590Srgrimes * '}' */ 4671590Srgrimes if (s_com != e_com) { /* the turkey has embedded a comment 4681590Srgrimes * in a line. fix it */ 4691590Srgrimes *e_code++ = ' '; 4701590Srgrimes for (t_ptr = s_com; *t_ptr; ++t_ptr) { 4711590Srgrimes CHECK_SIZE_CODE; 4721590Srgrimes *e_code++ = *t_ptr; 4731590Srgrimes } 4741590Srgrimes *e_code++ = ' '; 4751590Srgrimes *e_code = '\0'; /* null terminate code sect */ 4761590Srgrimes ps.want_blank = false; 4771590Srgrimes e_com = s_com; 4781590Srgrimes } 4791590Srgrimes } 4801590Srgrimes else if (type_code != comment) /* preserve force_nl thru a comment */ 4811590Srgrimes force_nl = false; /* cancel forced newline after newline, form 4821590Srgrimes * feed, etc */ 4831590Srgrimes 4841590Srgrimes 4851590Srgrimes 4861590Srgrimes /*-----------------------------------------------------*\ 4871590Srgrimes | do switch on type of token scanned | 4881590Srgrimes \*-----------------------------------------------------*/ 4891590Srgrimes CHECK_SIZE_CODE; 4901590Srgrimes switch (type_code) { /* now, decide what to do with the token */ 4911590Srgrimes 4921590Srgrimes case form_feed: /* found a form feed in line */ 4931590Srgrimes ps.use_ff = true; /* a form feed is treated much like a newline */ 4941590Srgrimes dump_line(); 4951590Srgrimes ps.want_blank = false; 4961590Srgrimes break; 4971590Srgrimes 4981590Srgrimes case newline: 4991590Srgrimes if (ps.last_token != comma || ps.p_l_follow > 0 5001590Srgrimes || !ps.leave_comma || ps.block_init || !break_comma || s_com != e_com) { 5011590Srgrimes dump_line(); 5021590Srgrimes ps.want_blank = false; 5031590Srgrimes } 5041590Srgrimes ++line_no; /* keep track of input line number */ 5051590Srgrimes break; 5061590Srgrimes 5071590Srgrimes case lparen: /* got a '(' or '[' */ 5081590Srgrimes ++ps.p_l_follow; /* count parens to make Healy happy */ 5091590Srgrimes if (ps.want_blank && *token != '[' && 5101590Srgrimes (ps.last_token != ident || proc_calls_space 5111590Srgrimes || (ps.its_a_keyword && (!ps.sizeof_keyword || Bill_Shannon)))) 5121590Srgrimes *e_code++ = ' '; 5131590Srgrimes if (ps.in_decl && !ps.block_init) 5141590Srgrimes if (troff && !ps.dumped_decl_indent && !is_procname && ps.last_token == decl) { 5151590Srgrimes ps.dumped_decl_indent = 1; 5161590Srgrimes sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); 5171590Srgrimes e_code += strlen(e_code); 5181590Srgrimes } 5191590Srgrimes else { 5201590Srgrimes while ((e_code - s_code) < dec_ind) { 5211590Srgrimes CHECK_SIZE_CODE; 5221590Srgrimes *e_code++ = ' '; 5231590Srgrimes } 5241590Srgrimes *e_code++ = token[0]; 5251590Srgrimes } 5261590Srgrimes else 5271590Srgrimes *e_code++ = token[0]; 5281590Srgrimes ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code; 5291590Srgrimes if (sp_sw && ps.p_l_follow == 1 && extra_expression_indent 5301590Srgrimes && ps.paren_indents[0] < 2 * ps.ind_size) 5311590Srgrimes ps.paren_indents[0] = 2 * ps.ind_size; 5321590Srgrimes ps.want_blank = false; 5331590Srgrimes if (ps.in_or_st && *token == '(' && ps.tos <= 2) { 5341590Srgrimes /* 5351590Srgrimes * this is a kluge to make sure that declarations will be 5361590Srgrimes * aligned right if proc decl has an explicit type on it, i.e. 5371590Srgrimes * "int a(x) {..." 5381590Srgrimes */ 5391590Srgrimes parse(semicolon); /* I said this was a kluge... */ 5401590Srgrimes ps.in_or_st = false; /* turn off flag for structure decl or 5411590Srgrimes * initialization */ 5421590Srgrimes } 5431590Srgrimes if (ps.sizeof_keyword) 5441590Srgrimes ps.sizeof_mask |= 1 << ps.p_l_follow; 5451590Srgrimes break; 5461590Srgrimes 5471590Srgrimes case rparen: /* got a ')' or ']' */ 5481590Srgrimes rparen_count--; 5491590Srgrimes if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask) { 5501590Srgrimes ps.last_u_d = true; 5511590Srgrimes ps.cast_mask &= (1 << ps.p_l_follow) - 1; 55269795Sobrien ps.want_blank = false; 55369795Sobrien } else 55469795Sobrien ps.want_blank = true; 5551590Srgrimes ps.sizeof_mask &= (1 << ps.p_l_follow) - 1; 5561590Srgrimes if (--ps.p_l_follow < 0) { 5571590Srgrimes ps.p_l_follow = 0; 55885632Sschweikh diag3(0, "Extra %c", *token); 5591590Srgrimes } 5601590Srgrimes if (e_code == s_code) /* if the paren starts the line */ 5611590Srgrimes ps.paren_level = ps.p_l_follow; /* then indent it */ 5621590Srgrimes 5631590Srgrimes *e_code++ = token[0]; 5641590Srgrimes 5651590Srgrimes if (sp_sw && (ps.p_l_follow == 0)) { /* check for end of if 5661590Srgrimes * (...), or some such */ 5671590Srgrimes sp_sw = false; 5681590Srgrimes force_nl = true;/* must force newline after if */ 5691590Srgrimes ps.last_u_d = true; /* inform lexi that a following 5701590Srgrimes * operator is unary */ 5711590Srgrimes ps.in_stmt = false; /* dont use stmt continuation 5721590Srgrimes * indentation */ 5731590Srgrimes 5741590Srgrimes parse(hd_type); /* let parser worry about if, or whatever */ 5751590Srgrimes } 5761590Srgrimes ps.search_brace = btype_2; /* this should insure that constructs 5771590Srgrimes * such as main(){...} and int[]{...} 5781590Srgrimes * have their braces put in the right 5791590Srgrimes * place */ 5801590Srgrimes break; 5811590Srgrimes 5821590Srgrimes case unary_op: /* this could be any unary operation */ 5831590Srgrimes if (ps.want_blank) 5841590Srgrimes *e_code++ = ' '; 5851590Srgrimes 5861590Srgrimes if (troff && !ps.dumped_decl_indent && ps.in_decl && !is_procname) { 5871590Srgrimes sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); 5881590Srgrimes ps.dumped_decl_indent = 1; 5891590Srgrimes e_code += strlen(e_code); 5901590Srgrimes } 5911590Srgrimes else { 59293440Sdwmalone const char *res = token; 5931590Srgrimes 5941590Srgrimes if (ps.in_decl && !ps.block_init) { /* if this is a unary op 5951590Srgrimes * in a declaration, we 5961590Srgrimes * should indent this 5971590Srgrimes * token */ 5981590Srgrimes for (i = 0; token[i]; ++i); /* find length of token */ 5991590Srgrimes while ((e_code - s_code) < (dec_ind - i)) { 6001590Srgrimes CHECK_SIZE_CODE; 6011590Srgrimes *e_code++ = ' '; /* pad it */ 6021590Srgrimes } 6031590Srgrimes } 6041590Srgrimes if (troff && token[0] == '-' && token[1] == '>') 6051590Srgrimes res = "\\(->"; 6061590Srgrimes for (t_ptr = res; *t_ptr; ++t_ptr) { 6071590Srgrimes CHECK_SIZE_CODE; 6081590Srgrimes *e_code++ = *t_ptr; 6091590Srgrimes } 6101590Srgrimes } 6111590Srgrimes ps.want_blank = false; 6121590Srgrimes break; 6131590Srgrimes 6141590Srgrimes case binary_op: /* any binary operation */ 6151590Srgrimes if (ps.want_blank) 6161590Srgrimes *e_code++ = ' '; 6171590Srgrimes { 61893440Sdwmalone const char *res = token; 6191590Srgrimes 6201590Srgrimes if (troff) 6211590Srgrimes switch (token[0]) { 6221590Srgrimes case '<': 6231590Srgrimes if (token[1] == '=') 6241590Srgrimes res = "\\(<="; 6251590Srgrimes break; 6261590Srgrimes case '>': 6271590Srgrimes if (token[1] == '=') 6281590Srgrimes res = "\\(>="; 6291590Srgrimes break; 6301590Srgrimes case '!': 6311590Srgrimes if (token[1] == '=') 6321590Srgrimes res = "\\(!="; 6331590Srgrimes break; 6341590Srgrimes case '|': 6351590Srgrimes if (token[1] == '|') 6361590Srgrimes res = "\\(br\\(br"; 6371590Srgrimes else if (token[1] == 0) 6381590Srgrimes res = "\\(br"; 6391590Srgrimes break; 6401590Srgrimes } 6411590Srgrimes for (t_ptr = res; *t_ptr; ++t_ptr) { 6421590Srgrimes CHECK_SIZE_CODE; 6431590Srgrimes *e_code++ = *t_ptr; /* move the operator */ 6441590Srgrimes } 6451590Srgrimes } 6461590Srgrimes ps.want_blank = true; 6471590Srgrimes break; 6481590Srgrimes 6491590Srgrimes case postop: /* got a trailing ++ or -- */ 6501590Srgrimes *e_code++ = token[0]; 6511590Srgrimes *e_code++ = token[1]; 6521590Srgrimes ps.want_blank = true; 6531590Srgrimes break; 6541590Srgrimes 6551590Srgrimes case question: /* got a ? */ 6561590Srgrimes squest++; /* this will be used when a later colon 6571590Srgrimes * appears so we can distinguish the 6581590Srgrimes * <c>?<n>:<n> construct */ 6591590Srgrimes if (ps.want_blank) 6601590Srgrimes *e_code++ = ' '; 6611590Srgrimes *e_code++ = '?'; 6621590Srgrimes ps.want_blank = true; 6631590Srgrimes break; 6641590Srgrimes 6651590Srgrimes case casestmt: /* got word 'case' or 'default' */ 6661590Srgrimes scase = true; /* so we can process the later colon properly */ 6671590Srgrimes goto copy_id; 6681590Srgrimes 6691590Srgrimes case colon: /* got a ':' */ 6701590Srgrimes if (squest > 0) { /* it is part of the <c>?<n>: <n> construct */ 6711590Srgrimes --squest; 6721590Srgrimes if (ps.want_blank) 6731590Srgrimes *e_code++ = ' '; 6741590Srgrimes *e_code++ = ':'; 6751590Srgrimes ps.want_blank = true; 6761590Srgrimes break; 6771590Srgrimes } 678205988Savg if (ps.in_or_st) { 6791590Srgrimes *e_code++ = ':'; 6801590Srgrimes ps.want_blank = false; 6811590Srgrimes break; 6821590Srgrimes } 6831590Srgrimes ps.in_stmt = false; /* seeing a label does not imply we are in a 6841590Srgrimes * stmt */ 6851590Srgrimes for (t_ptr = s_code; *t_ptr; ++t_ptr) 6861590Srgrimes *e_lab++ = *t_ptr; /* turn everything so far into a label */ 6871590Srgrimes e_code = s_code; 6881590Srgrimes *e_lab++ = ':'; 6891590Srgrimes *e_lab++ = ' '; 6901590Srgrimes *e_lab = '\0'; 6911590Srgrimes 6921590Srgrimes force_nl = ps.pcase = scase; /* ps.pcase will be used by 6931590Srgrimes * dump_line to decide how to 6941590Srgrimes * indent the label. force_nl 6951590Srgrimes * will force a case n: to be 6961590Srgrimes * on a line by itself */ 6971590Srgrimes scase = false; 6981590Srgrimes ps.want_blank = false; 6991590Srgrimes break; 7001590Srgrimes 7011590Srgrimes case semicolon: /* got a ';' */ 7021590Srgrimes ps.in_or_st = false;/* we are not in an initialization or 7031590Srgrimes * structure declaration */ 704108533Sschweikh scase = false; /* these will only need resetting in an error */ 7051590Srgrimes squest = 0; 7061590Srgrimes if (ps.last_token == rparen && rparen_count == 0) 7071590Srgrimes ps.in_parameter_declaration = 0; 7081590Srgrimes ps.cast_mask = 0; 7091590Srgrimes ps.sizeof_mask = 0; 7101590Srgrimes ps.block_init = 0; 7111590Srgrimes ps.block_init_level = 0; 7121590Srgrimes ps.just_saw_decl--; 7131590Srgrimes 7141590Srgrimes if (ps.in_decl && s_code == e_code && !ps.block_init) 7151590Srgrimes while ((e_code - s_code) < (dec_ind - 1)) { 7161590Srgrimes CHECK_SIZE_CODE; 7171590Srgrimes *e_code++ = ' '; 7181590Srgrimes } 7191590Srgrimes 7201590Srgrimes ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level 7211590Srgrimes * structure declaration, we 7221590Srgrimes * arent any more */ 7231590Srgrimes 7241590Srgrimes if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) { 7251590Srgrimes 7261590Srgrimes /* 7271590Srgrimes * This should be true iff there were unbalanced parens in the 7281590Srgrimes * stmt. It is a bit complicated, because the semicolon might 7291590Srgrimes * be in a for stmt 7301590Srgrimes */ 73185632Sschweikh diag2(1, "Unbalanced parens"); 7321590Srgrimes ps.p_l_follow = 0; 733108533Sschweikh if (sp_sw) { /* this is a check for an if, while, etc. with 7341590Srgrimes * unbalanced parens */ 7351590Srgrimes sp_sw = false; 7361590Srgrimes parse(hd_type); /* dont lose the if, or whatever */ 7371590Srgrimes } 7381590Srgrimes } 7391590Srgrimes *e_code++ = ';'; 7401590Srgrimes ps.want_blank = true; 7411590Srgrimes ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the 7421590Srgrimes * middle of a stmt */ 7431590Srgrimes 7441590Srgrimes if (!sp_sw) { /* if not if for (;;) */ 7451590Srgrimes parse(semicolon); /* let parser know about end of stmt */ 746108533Sschweikh force_nl = true;/* force newline after an end of stmt */ 7471590Srgrimes } 7481590Srgrimes break; 7491590Srgrimes 7501590Srgrimes case lbrace: /* got a '{' */ 7511590Srgrimes ps.in_stmt = false; /* dont indent the {} */ 7521590Srgrimes if (!ps.block_init) 7531590Srgrimes force_nl = true;/* force other stuff on same line as '{' onto 7541590Srgrimes * new line */ 7551590Srgrimes else if (ps.block_init_level <= 0) 7561590Srgrimes ps.block_init_level = 1; 7571590Srgrimes else 7581590Srgrimes ps.block_init_level++; 7591590Srgrimes 7601590Srgrimes if (s_code != e_code && !ps.block_init) { 7611590Srgrimes if (!btype_2) { 7621590Srgrimes dump_line(); 7631590Srgrimes ps.want_blank = false; 7641590Srgrimes } 7651590Srgrimes else if (ps.in_parameter_declaration && !ps.in_or_st) { 7661590Srgrimes ps.i_l_follow = 0; 767131184Sschweikh if (function_brace_split) { /* dump the line prior to the 768131184Sschweikh * brace ... */ 769131184Sschweikh dump_line(); 770131184Sschweikh ps.want_blank = false; 771131184Sschweikh } else /* add a space between the decl and brace */ 772131184Sschweikh ps.want_blank = true; 7731590Srgrimes } 7741590Srgrimes } 7751590Srgrimes if (ps.in_parameter_declaration) 7761590Srgrimes prefix_blankline_requested = 0; 7771590Srgrimes 77872645Sasmodai if (ps.p_l_follow > 0) { /* check for preceding unbalanced 7791590Srgrimes * parens */ 78085632Sschweikh diag2(1, "Unbalanced parens"); 7811590Srgrimes ps.p_l_follow = 0; 7821590Srgrimes if (sp_sw) { /* check for unclosed if, for, etc. */ 7831590Srgrimes sp_sw = false; 7841590Srgrimes parse(hd_type); 7851590Srgrimes ps.ind_level = ps.i_l_follow; 7861590Srgrimes } 7871590Srgrimes } 7881590Srgrimes if (s_code == e_code) 7891590Srgrimes ps.ind_stmt = false; /* dont put extra indentation on line 7901590Srgrimes * with '{' */ 7911590Srgrimes if (ps.in_decl && ps.in_or_st) { /* this is either a structure 7921590Srgrimes * declaration or an init */ 7931590Srgrimes di_stack[ps.dec_nest++] = dec_ind; 7941590Srgrimes /* ? dec_ind = 0; */ 7951590Srgrimes } 7961590Srgrimes else { 797228992Suqs ps.decl_on_line = false; /* we can't be in the middle of 798228992Suqs * a declaration, so don't do 7991590Srgrimes * special indentation of 8001590Srgrimes * comments */ 8011590Srgrimes if (blanklines_after_declarations_at_proctop 8021590Srgrimes && ps.in_parameter_declaration) 8031590Srgrimes postfix_blankline_requested = 1; 8041590Srgrimes ps.in_parameter_declaration = 0; 8051590Srgrimes } 8061590Srgrimes dec_ind = 0; 8071590Srgrimes parse(lbrace); /* let parser know about this */ 8081590Srgrimes if (ps.want_blank) /* put a blank before '{' if '{' is not at 8091590Srgrimes * start of line */ 8101590Srgrimes *e_code++ = ' '; 8111590Srgrimes ps.want_blank = false; 8121590Srgrimes *e_code++ = '{'; 8131590Srgrimes ps.just_saw_decl = 0; 8141590Srgrimes break; 8151590Srgrimes 8161590Srgrimes case rbrace: /* got a '}' */ 8171590Srgrimes if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be 8181590Srgrimes * omitted in 8191590Srgrimes * declarations */ 8201590Srgrimes parse(semicolon); 8211590Srgrimes if (ps.p_l_follow) {/* check for unclosed if, for, else. */ 82285632Sschweikh diag2(1, "Unbalanced parens"); 8231590Srgrimes ps.p_l_follow = 0; 8241590Srgrimes sp_sw = false; 8251590Srgrimes } 8261590Srgrimes ps.just_saw_decl = 0; 8271590Srgrimes ps.block_init_level--; 8281590Srgrimes if (s_code != e_code && !ps.block_init) { /* '}' must be first on 8291590Srgrimes * line */ 8301590Srgrimes if (verbose) 83185632Sschweikh diag2(0, "Line broken"); 8321590Srgrimes dump_line(); 8331590Srgrimes } 8341590Srgrimes *e_code++ = '}'; 8351590Srgrimes ps.want_blank = true; 8361590Srgrimes ps.in_stmt = ps.ind_stmt = false; 8371590Srgrimes if (ps.dec_nest > 0) { /* we are in multi-level structure 8381590Srgrimes * declaration */ 8391590Srgrimes dec_ind = di_stack[--ps.dec_nest]; 8401590Srgrimes if (ps.dec_nest == 0 && !ps.in_parameter_declaration) 8411590Srgrimes ps.just_saw_decl = 2; 8421590Srgrimes ps.in_decl = true; 8431590Srgrimes } 8441590Srgrimes prefix_blankline_requested = 0; 8451590Srgrimes parse(rbrace); /* let parser know about this */ 8461590Srgrimes ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead 8471590Srgrimes && ps.il[ps.tos] >= ps.ind_level; 8481590Srgrimes if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0) 8491590Srgrimes postfix_blankline_requested = 1; 8501590Srgrimes break; 8511590Srgrimes 8521590Srgrimes case swstmt: /* got keyword "switch" */ 8531590Srgrimes sp_sw = true; 8541590Srgrimes hd_type = swstmt; /* keep this for when we have seen the 8551590Srgrimes * expression */ 8561590Srgrimes goto copy_id; /* go move the token into buffer */ 8571590Srgrimes 8581590Srgrimes case sp_paren: /* token is if, while, for */ 8591590Srgrimes sp_sw = true; /* the interesting stuff is done after the 8601590Srgrimes * expression is scanned */ 8611590Srgrimes hd_type = (*token == 'i' ? ifstmt : 8621590Srgrimes (*token == 'w' ? whilestmt : forstmt)); 8631590Srgrimes 8641590Srgrimes /* 8651590Srgrimes * remember the type of header for later use by parser 8661590Srgrimes */ 8671590Srgrimes goto copy_id; /* copy the token into line */ 8681590Srgrimes 8691590Srgrimes case sp_nparen: /* got else, do */ 8701590Srgrimes ps.in_stmt = false; 8711590Srgrimes if (*token == 'e') { 8721590Srgrimes if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) { 8731590Srgrimes if (verbose) 87485632Sschweikh diag2(0, "Line broken"); 8751590Srgrimes dump_line();/* make sure this starts a line */ 8761590Srgrimes ps.want_blank = false; 8771590Srgrimes } 8781590Srgrimes force_nl = true;/* also, following stuff must go onto new line */ 8791590Srgrimes last_else = 1; 8801590Srgrimes parse(elselit); 8811590Srgrimes } 8821590Srgrimes else { 8831590Srgrimes if (e_code != s_code) { /* make sure this starts a line */ 8841590Srgrimes if (verbose) 88585632Sschweikh diag2(0, "Line broken"); 8861590Srgrimes dump_line(); 8871590Srgrimes ps.want_blank = false; 8881590Srgrimes } 8891590Srgrimes force_nl = true;/* also, following stuff must go onto new line */ 8901590Srgrimes last_else = 0; 8911590Srgrimes parse(dolit); 8921590Srgrimes } 8931590Srgrimes goto copy_id; /* move the token into line */ 8941590Srgrimes 8951590Srgrimes case decl: /* we have a declaration type (int, register, 8961590Srgrimes * etc.) */ 8971590Srgrimes parse(decl); /* let parser worry about indentation */ 8981590Srgrimes if (ps.last_token == rparen && ps.tos <= 1) { 8991590Srgrimes ps.in_parameter_declaration = 1; 9001590Srgrimes if (s_code != e_code) { 9011590Srgrimes dump_line(); 9021590Srgrimes ps.want_blank = 0; 9031590Srgrimes } 9041590Srgrimes } 9051590Srgrimes if (ps.in_parameter_declaration && ps.indent_parameters && ps.dec_nest == 0) { 9061590Srgrimes ps.ind_level = ps.i_l_follow = 1; 9071590Srgrimes ps.ind_stmt = 0; 9081590Srgrimes } 9091590Srgrimes ps.in_or_st = true; /* this might be a structure or initialization 9101590Srgrimes * declaration */ 9111590Srgrimes ps.in_decl = ps.decl_on_line = true; 9121590Srgrimes if ( /* !ps.in_or_st && */ ps.dec_nest <= 0) 9131590Srgrimes ps.just_saw_decl = 2; 9141590Srgrimes prefix_blankline_requested = 0; 9151590Srgrimes for (i = 0; token[i++];); /* get length of token */ 9161590Srgrimes 917125633Sbde if (ps.ind_level == 0 || ps.dec_nest > 0) { 918125633Sbde /* global variable or struct member in local variable */ 919125633Sbde dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i; 920131184Sschweikh tabs_to_var = (use_tabs ? ps.decl_indent > 0 : 0); 921125633Sbde } else { 922125633Sbde /* local variable */ 923125633Sbde dec_ind = ps.local_decl_indent > 0 ? ps.local_decl_indent : i; 924131184Sschweikh tabs_to_var = (use_tabs ? ps.local_decl_indent > 0 : 0); 925125633Sbde } 9261590Srgrimes goto copy_id; 9271590Srgrimes 9281590Srgrimes case ident: /* got an identifier or constant */ 9291590Srgrimes if (ps.in_decl) { /* if we are in a declaration, we must indent 9301590Srgrimes * identifier */ 9311590Srgrimes if (is_procname == 0 || !procnames_start_line) { 93285632Sschweikh if (!ps.block_init) { 9331590Srgrimes if (troff && !ps.dumped_decl_indent) { 934125624Sbde if (ps.want_blank) 935125624Sbde *e_code++ = ' '; 936125624Sbde ps.want_blank = false; 9371590Srgrimes sprintf(e_code, "\n.De %dp+\200p\n", dec_ind * 7); 9381590Srgrimes ps.dumped_decl_indent = 1; 9391590Srgrimes e_code += strlen(e_code); 94085632Sschweikh } else { 941131184Sschweikh int cur_dec_ind; 942125624Sbde int pos, startpos; 943125624Sbde 944131184Sschweikh /* 945131184Sschweikh * in order to get the tab math right for 946131184Sschweikh * indentations that are not multiples of 8 we 947131184Sschweikh * need to modify both startpos and dec_ind 948131184Sschweikh * (cur_dec_ind) here by eight minus the 949131184Sschweikh * remainder of the current starting column 950131184Sschweikh * divided by eight. This seems to be a 951131184Sschweikh * properly working fix 952131184Sschweikh */ 953125624Sbde startpos = e_code - s_code; 954131184Sschweikh cur_dec_ind = dec_ind; 955125624Sbde pos = startpos; 956131184Sschweikh if ((ps.ind_level * ps.ind_size) % 8 != 0) { 957131184Sschweikh pos += (ps.ind_level * ps.ind_size) % 8; 958131184Sschweikh cur_dec_ind += (ps.ind_level * ps.ind_size) % 8; 959131184Sschweikh } 960131184Sschweikh 961131184Sschweikh if (tabs_to_var) { 962131184Sschweikh while ((pos & ~7) + 8 <= cur_dec_ind) { 963125631Sbde CHECK_SIZE_CODE; 964125631Sbde *e_code++ = '\t'; 965125631Sbde pos = (pos & ~7) + 8; 966125631Sbde } 967125624Sbde } 968131184Sschweikh while (pos < cur_dec_ind) { 969125624Sbde CHECK_SIZE_CODE; 9701590Srgrimes *e_code++ = ' '; 971125624Sbde pos++; 9721590Srgrimes } 973125624Sbde if (ps.want_blank && e_code - s_code == startpos) 974125624Sbde *e_code++ = ' '; 975125624Sbde ps.want_blank = false; 97685632Sschweikh } 97785632Sschweikh } 97885632Sschweikh } else { 979125624Sbde if (ps.want_blank) 980125624Sbde *e_code++ = ' '; 981125624Sbde ps.want_blank = false; 9821590Srgrimes if (dec_ind && s_code != e_code) 9831590Srgrimes dump_line(); 9841590Srgrimes dec_ind = 0; 9851590Srgrimes } 9861590Srgrimes } 9871590Srgrimes else if (sp_sw && ps.p_l_follow == 0) { 9881590Srgrimes sp_sw = false; 9891590Srgrimes force_nl = true; 9901590Srgrimes ps.last_u_d = true; 9911590Srgrimes ps.in_stmt = false; 9921590Srgrimes parse(hd_type); 9931590Srgrimes } 9941590Srgrimes copy_id: 9951590Srgrimes if (ps.want_blank) 9961590Srgrimes *e_code++ = ' '; 9971590Srgrimes if (troff && ps.its_a_keyword) { 9981590Srgrimes e_code = chfont(&bodyf, &keywordf, e_code); 9991590Srgrimes for (t_ptr = token; *t_ptr; ++t_ptr) { 10001590Srgrimes CHECK_SIZE_CODE; 10011590Srgrimes *e_code++ = keywordf.allcaps && islower(*t_ptr) 10021590Srgrimes ? toupper(*t_ptr) : *t_ptr; 10031590Srgrimes } 10041590Srgrimes e_code = chfont(&keywordf, &bodyf, e_code); 10051590Srgrimes } 10061590Srgrimes else 10071590Srgrimes for (t_ptr = token; *t_ptr; ++t_ptr) { 10081590Srgrimes CHECK_SIZE_CODE; 10091590Srgrimes *e_code++ = *t_ptr; 10101590Srgrimes } 10111590Srgrimes ps.want_blank = true; 10121590Srgrimes break; 10131590Srgrimes 10141590Srgrimes case period: /* treat a period kind of like a binary 10151590Srgrimes * operation */ 10161590Srgrimes *e_code++ = '.'; /* move the period into line */ 10171590Srgrimes ps.want_blank = false; /* dont put a blank after a period */ 10181590Srgrimes break; 10191590Srgrimes 10201590Srgrimes case comma: 10211590Srgrimes ps.want_blank = (s_code != e_code); /* only put blank after comma 10221590Srgrimes * if comma does not start the 10231590Srgrimes * line */ 10241590Srgrimes if (ps.in_decl && is_procname == 0 && !ps.block_init) 10251590Srgrimes while ((e_code - s_code) < (dec_ind - 1)) { 10261590Srgrimes CHECK_SIZE_CODE; 10271590Srgrimes *e_code++ = ' '; 10281590Srgrimes } 10291590Srgrimes 10301590Srgrimes *e_code++ = ','; 10311590Srgrimes if (ps.p_l_follow == 0) { 10321590Srgrimes if (ps.block_init_level <= 0) 10331590Srgrimes ps.block_init = 0; 10341590Srgrimes if (break_comma && (!ps.leave_comma || compute_code_target() + (e_code - s_code) > max_col - 8)) 10351590Srgrimes force_nl = true; 10361590Srgrimes } 10371590Srgrimes break; 10381590Srgrimes 10391590Srgrimes case preesc: /* got the character '#' */ 10401590Srgrimes if ((s_com != e_com) || 10411590Srgrimes (s_lab != e_lab) || 10421590Srgrimes (s_code != e_code)) 10431590Srgrimes dump_line(); 10441590Srgrimes *e_lab++ = '#'; /* move whole line to 'label' buffer */ 10451590Srgrimes { 10461590Srgrimes int in_comment = 0; 10471590Srgrimes int com_start = 0; 10481590Srgrimes char quote = 0; 10491590Srgrimes int com_end = 0; 10501590Srgrimes 10511590Srgrimes while (*buf_ptr == ' ' || *buf_ptr == '\t') { 10521590Srgrimes buf_ptr++; 10531590Srgrimes if (buf_ptr >= buf_end) 10541590Srgrimes fill_buffer(); 10551590Srgrimes } 105673175Sobrien while (*buf_ptr != '\n' || (in_comment && !had_eof)) { 10571590Srgrimes CHECK_SIZE_LAB; 10581590Srgrimes *e_lab = *buf_ptr++; 10591590Srgrimes if (buf_ptr >= buf_end) 10601590Srgrimes fill_buffer(); 10611590Srgrimes switch (*e_lab++) { 10621590Srgrimes case BACKSLASH: 10631590Srgrimes if (troff) 10641590Srgrimes *e_lab++ = BACKSLASH; 10651590Srgrimes if (!in_comment) { 10661590Srgrimes *e_lab++ = *buf_ptr++; 10671590Srgrimes if (buf_ptr >= buf_end) 10681590Srgrimes fill_buffer(); 10691590Srgrimes } 10701590Srgrimes break; 10711590Srgrimes case '/': 10721590Srgrimes if (*buf_ptr == '*' && !in_comment && !quote) { 10731590Srgrimes in_comment = 1; 10741590Srgrimes *e_lab++ = *buf_ptr++; 10751590Srgrimes com_start = e_lab - s_lab - 2; 10761590Srgrimes } 10771590Srgrimes break; 10781590Srgrimes case '"': 10791590Srgrimes if (quote == '"') 10801590Srgrimes quote = 0; 10811590Srgrimes break; 10821590Srgrimes case '\'': 10831590Srgrimes if (quote == '\'') 10841590Srgrimes quote = 0; 10851590Srgrimes break; 10861590Srgrimes case '*': 10871590Srgrimes if (*buf_ptr == '/' && in_comment) { 10881590Srgrimes in_comment = 0; 10891590Srgrimes *e_lab++ = *buf_ptr++; 10901590Srgrimes com_end = e_lab - s_lab; 10911590Srgrimes } 10921590Srgrimes break; 10931590Srgrimes } 10941590Srgrimes } 10951590Srgrimes 10961590Srgrimes while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 10971590Srgrimes e_lab--; 10981590Srgrimes if (e_lab - s_lab == com_end && bp_save == 0) { /* comment on 10991590Srgrimes * preprocessor line */ 11001590Srgrimes if (sc_end == 0) /* if this is the first comment, we 11011590Srgrimes * must set up the buffer */ 11021590Srgrimes sc_end = &(save_com[0]); 11031590Srgrimes else { 11041590Srgrimes *sc_end++ = '\n'; /* add newline between 11051590Srgrimes * comments */ 11061590Srgrimes *sc_end++ = ' '; 11071590Srgrimes --line_no; 11081590Srgrimes } 11091590Srgrimes bcopy(s_lab + com_start, sc_end, com_end - com_start); 11101590Srgrimes sc_end += com_end - com_start; 11111590Srgrimes if (sc_end >= &save_com[sc_size]) 11121590Srgrimes abort(); 11131590Srgrimes e_lab = s_lab + com_start; 11141590Srgrimes while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 11151590Srgrimes e_lab--; 11161590Srgrimes bp_save = buf_ptr; /* save current input buffer */ 11171590Srgrimes be_save = buf_end; 11181590Srgrimes buf_ptr = save_com; /* fix so that subsequent calls to 11191590Srgrimes * lexi will take tokens out of 11201590Srgrimes * save_com */ 11211590Srgrimes *sc_end++ = ' '; /* add trailing blank, just in case */ 11221590Srgrimes buf_end = sc_end; 11231590Srgrimes sc_end = 0; 11241590Srgrimes } 11251590Srgrimes *e_lab = '\0'; /* null terminate line */ 11261590Srgrimes ps.pcase = false; 11271590Srgrimes } 11281590Srgrimes 11291590Srgrimes if (strncmp(s_lab, "#if", 3) == 0) { 11301590Srgrimes if (blanklines_around_conditional_compilation) { 113198771Sjmallett int c; 11321590Srgrimes prefix_blankline_requested++; 11331590Srgrimes while ((c = getc(input)) == '\n'); 11341590Srgrimes ungetc(c, input); 11351590Srgrimes } 113693440Sdwmalone if ((size_t)ifdef_level < sizeof(state_stack)/sizeof(state_stack[0])) { 11371590Srgrimes match_state[ifdef_level].tos = -1; 11381590Srgrimes state_stack[ifdef_level++] = ps; 11391590Srgrimes } 11401590Srgrimes else 114185632Sschweikh diag2(1, "#if stack overflow"); 11421590Srgrimes } 11431590Srgrimes else if (strncmp(s_lab, "#else", 5) == 0) 11441590Srgrimes if (ifdef_level <= 0) 114585632Sschweikh diag2(1, "Unmatched #else"); 11461590Srgrimes else { 11471590Srgrimes match_state[ifdef_level - 1] = ps; 11481590Srgrimes ps = state_stack[ifdef_level - 1]; 11491590Srgrimes } 11501590Srgrimes else if (strncmp(s_lab, "#endif", 6) == 0) { 11511590Srgrimes if (ifdef_level <= 0) 115285632Sschweikh diag2(1, "Unmatched #endif"); 11531590Srgrimes else { 11541590Srgrimes ifdef_level--; 11551590Srgrimes 11561590Srgrimes#ifdef undef 11571590Srgrimes /* 11581590Srgrimes * This match needs to be more intelligent before the 11591590Srgrimes * message is useful 11601590Srgrimes */ 11611590Srgrimes if (match_state[ifdef_level].tos >= 0 11621590Srgrimes && bcmp(&ps, &match_state[ifdef_level], sizeof ps)) 1163116390Scharnier diag2(0, "Syntactically inconsistent #ifdef alternatives"); 11641590Srgrimes#endif 11651590Srgrimes } 11661590Srgrimes if (blanklines_around_conditional_compilation) { 11671590Srgrimes postfix_blankline_requested++; 11681590Srgrimes n_real_blanklines = 0; 11691590Srgrimes } 11701590Srgrimes } 11711590Srgrimes break; /* subsequent processing of the newline 11721590Srgrimes * character will cause the line to be printed */ 11731590Srgrimes 117485632Sschweikh case comment: /* we have gotten a / followed by * this is a biggie */ 11751590Srgrimes if (flushed_nl) { /* we should force a broken line here */ 11761590Srgrimes flushed_nl = false; 11771590Srgrimes dump_line(); 11781590Srgrimes ps.want_blank = false; /* dont insert blank at line start */ 11791590Srgrimes force_nl = false; 11801590Srgrimes } 11811590Srgrimes pr_comment(); 11821590Srgrimes break; 11831590Srgrimes } /* end of big switch stmt */ 11841590Srgrimes 11851590Srgrimes *e_code = '\0'; /* make sure code section is null terminated */ 11861590Srgrimes if (type_code != comment && type_code != newline && type_code != preesc) 11871590Srgrimes ps.last_token = type_code; 11881590Srgrimes } /* end of main while (1) loop */ 11891590Srgrimes} 11901590Srgrimes 11911590Srgrimes/* 11921590Srgrimes * copy input file to backup file if in_name is /blah/blah/blah/file, then 11931590Srgrimes * backup file will be ".Bfile" then make the backup file the input and 11941590Srgrimes * original input file the output 11951590Srgrimes */ 119685632Sschweikhstatic void 119785632Sschweikhbakcopy(void) 11981590Srgrimes{ 11991590Srgrimes int n, 12001590Srgrimes bakchn; 12011590Srgrimes char buff[8 * 1024]; 120293440Sdwmalone const char *p; 12031590Srgrimes 12041590Srgrimes /* construct file name .Bfile */ 12051590Srgrimes for (p = in_name; *p; p++); /* skip to end of string */ 12061590Srgrimes while (p > in_name && *p != '/') /* find last '/' */ 12071590Srgrimes p--; 12081590Srgrimes if (*p == '/') 12091590Srgrimes p++; 12101590Srgrimes sprintf(bakfile, "%s.BAK", p); 12111590Srgrimes 12121590Srgrimes /* copy in_name to backup file */ 12131590Srgrimes bakchn = creat(bakfile, 0600); 12141590Srgrimes if (bakchn < 0) 121562894Skris err(1, "%s", bakfile); 121685632Sschweikh while ((n = read(fileno(input), buff, sizeof buff)) != 0) 12171590Srgrimes if (write(bakchn, buff, n) != n) 121862894Skris err(1, "%s", bakfile); 12191590Srgrimes if (n < 0) 122062894Skris err(1, "%s", in_name); 12211590Srgrimes close(bakchn); 12221590Srgrimes fclose(input); 12231590Srgrimes 12241590Srgrimes /* re-open backup file as the input file */ 12251590Srgrimes input = fopen(bakfile, "r"); 1226211132Skevlo if (input == NULL) 122762894Skris err(1, "%s", bakfile); 12281590Srgrimes /* now the original input file will be the output */ 12291590Srgrimes output = fopen(in_name, "w"); 1230211132Skevlo if (output == NULL) { 12311590Srgrimes unlink(bakfile); 123262894Skris err(1, "%s", in_name); 12331590Srgrimes } 12341590Srgrimes} 1235