indent.c revision 105244
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 441590Srgrimes#ifndef lint 4527419Scharnier#if 0 461590Srgrimesstatic char sccsid[] = "@(#)indent.c 5.17 (Berkeley) 6/7/93"; 4727419Scharnier#endif 481590Srgrimes#endif /* not lint */ 4999112Sobrien#include <sys/cdefs.h> 5099112Sobrien__FBSDID("$FreeBSD: head/usr.bin/indent/indent.c 105244 2002-10-16 13:58:39Z charnier $"); 511590Srgrimes 521590Srgrimes#include <sys/param.h> 5327419Scharnier#include <err.h> 541590Srgrimes#include <fcntl.h> 551590Srgrimes#include <unistd.h> 561590Srgrimes#include <stdio.h> 571590Srgrimes#include <stdlib.h> 581590Srgrimes#include <string.h> 5985632Sschweikh#include <ctype.h> 601590Srgrimes#include "indent_globs.h" 611590Srgrimes#include "indent_codes.h" 6285632Sschweikh#include "indent.h" 631590Srgrimes 6485632Sschweikhstatic void bakcopy(void); 6585632Sschweikh 6693440Sdwmaloneconst char *in_name = "Standard Input"; /* will always point to name of input 671590Srgrimes * file */ 6893440Sdwmaloneconst char *out_name = "Standard Output"; /* will always point to name 691590Srgrimes * of output file */ 701590Srgrimeschar bakfile[MAXPATHLEN] = ""; 711590Srgrimes 7285632Sschweikhint 7385632Sschweikhmain(int argc, char **argv) 741590Srgrimes{ 751590Srgrimes 7685632Sschweikh extern int found_err; /* flag set in diagN() on error */ 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 */ 8498771Sjmallett 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 */ 931590Srgrimes int type_code; /* the type of token, returned by lexi */ 941590Srgrimes 951590Srgrimes int last_else = 0; /* true iff last keyword was an else */ 961590Srgrimes 971590Srgrimes 981590Srgrimes /*-----------------------------------------------*\ 991590Srgrimes | INITIALIZATION | 1001590Srgrimes \*-----------------------------------------------*/ 1011590Srgrimes 1021590Srgrimes 1031590Srgrimes ps.p_stack[0] = stmt; /* this is the parser's stack */ 1041590Srgrimes ps.last_nl = true; /* this is true if the last thing scanned was 1051590Srgrimes * a newline */ 1061590Srgrimes ps.last_token = semicolon; 1071590Srgrimes combuf = (char *) malloc(bufsize); 1081590Srgrimes labbuf = (char *) malloc(bufsize); 1091590Srgrimes codebuf = (char *) malloc(bufsize); 1101590Srgrimes tokenbuf = (char *) malloc(bufsize); 1111590Srgrimes l_com = combuf + bufsize - 5; 1121590Srgrimes l_lab = labbuf + bufsize - 5; 1131590Srgrimes l_code = codebuf + bufsize - 5; 1141590Srgrimes l_token = tokenbuf + bufsize - 5; 1151590Srgrimes combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and 1161590Srgrimes * comment buffers */ 1171590Srgrimes combuf[1] = codebuf[1] = labbuf[1] = '\0'; 1181590Srgrimes ps.else_if = 1; /* Default else-if special processing to on */ 1191590Srgrimes s_lab = e_lab = labbuf + 1; 1201590Srgrimes s_code = e_code = codebuf + 1; 1211590Srgrimes s_com = e_com = combuf + 1; 1221590Srgrimes s_token = e_token = tokenbuf + 1; 1231590Srgrimes 1241590Srgrimes in_buffer = (char *) malloc(10); 1251590Srgrimes in_buffer_limit = in_buffer + 8; 1261590Srgrimes buf_ptr = buf_end = in_buffer; 1271590Srgrimes line_no = 1; 1281590Srgrimes had_eof = ps.in_decl = ps.decl_on_line = break_comma = false; 1291590Srgrimes sp_sw = force_nl = false; 1301590Srgrimes ps.in_or_st = false; 1311590Srgrimes ps.bl_line = true; 1321590Srgrimes dec_ind = 0; 1331590Srgrimes di_stack[ps.dec_nest = 0] = 0; 1341590Srgrimes ps.want_blank = ps.in_stmt = ps.ind_stmt = false; 1351590Srgrimes 1361590Srgrimes 1371590Srgrimes scase = ps.pcase = false; 1381590Srgrimes squest = 0; 1391590Srgrimes sc_end = 0; 1401590Srgrimes bp_save = 0; 1411590Srgrimes be_save = 0; 1421590Srgrimes 1431590Srgrimes output = 0; 1441590Srgrimes 1451590Srgrimes 1461590Srgrimes 1471590Srgrimes /*--------------------------------------------------*\ 1481590Srgrimes | COMMAND LINE SCAN | 1491590Srgrimes \*--------------------------------------------------*/ 1501590Srgrimes 1511590Srgrimes#ifdef undef 1521590Srgrimes max_col = 78; /* -l78 */ 1531590Srgrimes lineup_to_parens = 1; /* -lp */ 1541590Srgrimes ps.ljust_decl = 0; /* -ndj */ 1551590Srgrimes ps.com_ind = 33; /* -c33 */ 1561590Srgrimes star_comment_cont = 1; /* -sc */ 1571590Srgrimes ps.ind_size = 8; /* -i8 */ 1581590Srgrimes verbose = 0; 1591590Srgrimes ps.decl_indent = 16; /* -di16 */ 1601590Srgrimes ps.indent_parameters = 1; /* -ip */ 1611590Srgrimes ps.decl_com_ind = 0; /* if this is not set to some positive value 1621590Srgrimes * by an arg, we will set this equal to 1631590Srgrimes * ps.com_ind */ 1641590Srgrimes btype_2 = 1; /* -br */ 1651590Srgrimes cuddle_else = 1; /* -ce */ 1661590Srgrimes ps.unindent_displace = 0; /* -d0 */ 1671590Srgrimes ps.case_indent = 0; /* -cli0 */ 16869795Sobrien format_block_comments = 1; /* -fcb */ 1691590Srgrimes format_col1_comments = 1; /* -fc1 */ 1701590Srgrimes procnames_start_line = 1; /* -psl */ 1711590Srgrimes proc_calls_space = 0; /* -npcs */ 1721590Srgrimes comment_delimiter_on_blankline = 1; /* -cdb */ 1731590Srgrimes ps.leave_comma = 1; /* -nbc */ 1741590Srgrimes#endif 1751590Srgrimes 1761590Srgrimes for (i = 1; i < argc; ++i) 1771590Srgrimes if (strcmp(argv[i], "-npro") == 0) 1781590Srgrimes break; 1791590Srgrimes set_defaults(); 1801590Srgrimes if (i >= argc) 1811590Srgrimes set_profile(); 1821590Srgrimes 1831590Srgrimes for (i = 1; i < argc; ++i) { 1841590Srgrimes 1851590Srgrimes /* 1861590Srgrimes * look thru args (if any) for changes to defaults 1871590Srgrimes */ 1881590Srgrimes if (argv[i][0] != '-') {/* no flag on parameter */ 1891590Srgrimes if (input == 0) { /* we must have the input file */ 1901590Srgrimes in_name = argv[i]; /* remember name of input file */ 1911590Srgrimes input = fopen(in_name, "r"); 1921590Srgrimes if (input == 0) /* check for open error */ 19362894Skris err(1, "%s", in_name); 1941590Srgrimes continue; 1951590Srgrimes } 1961590Srgrimes else if (output == 0) { /* we have the output file */ 1971590Srgrimes out_name = argv[i]; /* remember name of output file */ 1981590Srgrimes if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite 1991590Srgrimes * the file */ 20027419Scharnier errx(1, "input and output files must be different"); 2011590Srgrimes } 2021590Srgrimes output = fopen(out_name, "w"); 2031590Srgrimes if (output == 0) /* check for create error */ 20462894Skris err(1, "%s", out_name); 2051590Srgrimes continue; 2061590Srgrimes } 20727419Scharnier errx(1, "unknown parameter: %s", argv[i]); 2081590Srgrimes } 2091590Srgrimes else 2101590Srgrimes set_option(argv[i]); 2111590Srgrimes } /* end of for */ 21248566Sbillf if (input == 0) 21340502Sthepish input = stdin; 21448566Sbillf if (output == 0) { 21540502Sthepish if (troff || input == stdin) 2161590Srgrimes output = stdout; 2171590Srgrimes else { 2181590Srgrimes out_name = in_name; 2191590Srgrimes bakcopy(); 2201590Srgrimes } 22148566Sbillf } 2221590Srgrimes if (ps.com_ind <= 1) 2231590Srgrimes ps.com_ind = 2; /* dont put normal comments before column 2 */ 2241590Srgrimes if (troff) { 2251590Srgrimes if (bodyf.font[0] == 0) 2261590Srgrimes parsefont(&bodyf, "R"); 2271590Srgrimes if (scomf.font[0] == 0) 2281590Srgrimes parsefont(&scomf, "I"); 2291590Srgrimes if (blkcomf.font[0] == 0) 2301590Srgrimes blkcomf = scomf, blkcomf.size += 2; 2311590Srgrimes if (boxcomf.font[0] == 0) 2321590Srgrimes boxcomf = blkcomf; 2331590Srgrimes if (stringf.font[0] == 0) 2341590Srgrimes parsefont(&stringf, "L"); 2351590Srgrimes if (keywordf.font[0] == 0) 2361590Srgrimes parsefont(&keywordf, "B"); 2371590Srgrimes writefdef(&bodyf, 'B'); 2381590Srgrimes writefdef(&scomf, 'C'); 2391590Srgrimes writefdef(&blkcomf, 'L'); 2401590Srgrimes writefdef(&boxcomf, 'X'); 2411590Srgrimes writefdef(&stringf, 'S'); 2421590Srgrimes writefdef(&keywordf, 'K'); 2431590Srgrimes } 2441590Srgrimes if (block_comment_max_col <= 0) 2451590Srgrimes block_comment_max_col = max_col; 2461590Srgrimes if (ps.decl_com_ind <= 0) /* if not specified by user, set this */ 2471590Srgrimes ps.decl_com_ind = ps.ljust_decl ? (ps.com_ind <= 10 ? 2 : ps.com_ind - 8) : ps.com_ind; 2481590Srgrimes if (continuation_indent == 0) 2491590Srgrimes continuation_indent = ps.ind_size; 2501590Srgrimes fill_buffer(); /* get first batch of stuff into input buffer */ 2511590Srgrimes 2521590Srgrimes parse(semicolon); 2531590Srgrimes { 25498771Sjmallett char *p = buf_ptr; 25598771Sjmallett int col = 1; 2561590Srgrimes 2571590Srgrimes while (1) { 2581590Srgrimes if (*p == ' ') 2591590Srgrimes col++; 2601590Srgrimes else if (*p == '\t') 2611590Srgrimes col = ((col - 1) & ~7) + 9; 2621590Srgrimes else 2631590Srgrimes break; 2641590Srgrimes p++; 2651590Srgrimes } 2661590Srgrimes if (col > ps.ind_size) 2671590Srgrimes ps.ind_level = ps.i_l_follow = col / ps.ind_size; 2681590Srgrimes } 2691590Srgrimes if (troff) { 27093440Sdwmalone const char *p = in_name, 2711590Srgrimes *beg = in_name; 2721590Srgrimes 2731590Srgrimes while (*p) 2741590Srgrimes if (*p++ == '/') 2751590Srgrimes beg = p; 2761590Srgrimes fprintf(output, ".Fn \"%s\"\n", beg); 2771590Srgrimes } 2781590Srgrimes /* 2791590Srgrimes * START OF MAIN LOOP 2801590Srgrimes */ 2811590Srgrimes 2821590Srgrimes while (1) { /* this is the main loop. it will go until we 2831590Srgrimes * reach eof */ 2841590Srgrimes int is_procname; 2851590Srgrimes 2861590Srgrimes type_code = lexi(); /* lexi reads one token. The actual 2871590Srgrimes * characters read are stored in "token". lexi 2881590Srgrimes * returns a code indicating the type of token */ 2891590Srgrimes is_procname = ps.procname[0]; 2901590Srgrimes 2911590Srgrimes /* 2921590Srgrimes * The following code moves everything following an if (), while (), 2931590Srgrimes * else, etc. up to the start of the following stmt to a buffer. This 2941590Srgrimes * allows proper handling of both kinds of brace placement. 2951590Srgrimes */ 2961590Srgrimes 2971590Srgrimes flushed_nl = false; 2981590Srgrimes while (ps.search_brace) { /* if we scanned an if(), while(), 2991590Srgrimes * etc., we might need to copy stuff 3001590Srgrimes * into a buffer we must loop, copying 3011590Srgrimes * stuff into save_com, until we find 3021590Srgrimes * the start of the stmt which follows 3031590Srgrimes * the if, or whatever */ 3041590Srgrimes switch (type_code) { 3051590Srgrimes case newline: 3061590Srgrimes ++line_no; 3071590Srgrimes flushed_nl = true; 3081590Srgrimes case form_feed: 3091590Srgrimes break; /* form feeds and newlines found here will be 3101590Srgrimes * ignored */ 3111590Srgrimes 3121590Srgrimes case lbrace: /* this is a brace that starts the compound 3131590Srgrimes * stmt */ 3141590Srgrimes if (sc_end == 0) { /* ignore buffering if a comment wasnt 3151590Srgrimes * stored up */ 3161590Srgrimes ps.search_brace = false; 3171590Srgrimes goto check_type; 3181590Srgrimes } 3191590Srgrimes if (btype_2) { 3201590Srgrimes save_com[0] = '{'; /* we either want to put the brace 3211590Srgrimes * right after the if */ 3221590Srgrimes goto sw_buffer; /* go to common code to get out of 3231590Srgrimes * this loop */ 3241590Srgrimes } 3251590Srgrimes case comment: /* we have a comment, so we must copy it into 3261590Srgrimes * the buffer */ 3271590Srgrimes if (!flushed_nl || sc_end != 0) { 3281590Srgrimes if (sc_end == 0) { /* if this is the first comment, we 3291590Srgrimes * must set up the buffer */ 3301590Srgrimes save_com[0] = save_com[1] = ' '; 3311590Srgrimes sc_end = &(save_com[2]); 3321590Srgrimes } 3331590Srgrimes else { 3341590Srgrimes *sc_end++ = '\n'; /* add newline between 3351590Srgrimes * comments */ 3361590Srgrimes *sc_end++ = ' '; 3371590Srgrimes --line_no; 3381590Srgrimes } 3391590Srgrimes *sc_end++ = '/'; /* copy in start of comment */ 3401590Srgrimes *sc_end++ = '*'; 3411590Srgrimes 3421590Srgrimes for (;;) { /* loop until we get to the end of the comment */ 3431590Srgrimes *sc_end = *buf_ptr++; 3441590Srgrimes if (buf_ptr >= buf_end) 3451590Srgrimes fill_buffer(); 3461590Srgrimes 3471590Srgrimes if (*sc_end++ == '*' && *buf_ptr == '/') 3481590Srgrimes break; /* we are at end of comment */ 3491590Srgrimes 3501590Srgrimes if (sc_end >= &(save_com[sc_size])) { /* check for temp buffer 3511590Srgrimes * overflow */ 35285632Sschweikh diag2(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever."); 3531590Srgrimes fflush(output); 3541590Srgrimes exit(1); 3551590Srgrimes } 3561590Srgrimes } 3571590Srgrimes *sc_end++ = '/'; /* add ending slash */ 3581590Srgrimes if (++buf_ptr >= buf_end) /* get past / in buffer */ 3591590Srgrimes fill_buffer(); 3601590Srgrimes break; 3611590Srgrimes } 362105244Scharnier default: /* it is the start of a normal statement */ 3631590Srgrimes if (flushed_nl) /* if we flushed a newline, make sure it is 3641590Srgrimes * put back */ 3651590Srgrimes force_nl = true; 36685632Sschweikh if ((type_code == sp_paren && *token == 'i' 36785632Sschweikh && last_else && ps.else_if) 36885632Sschweikh || (type_code == sp_nparen && *token == 'e' 36985632Sschweikh && e_code != s_code && e_code[-1] == '}')) 3701590Srgrimes force_nl = false; 3711590Srgrimes 3721590Srgrimes if (sc_end == 0) { /* ignore buffering if comment wasnt 3731590Srgrimes * saved up */ 3741590Srgrimes ps.search_brace = false; 3751590Srgrimes goto check_type; 3761590Srgrimes } 3771590Srgrimes if (force_nl) { /* if we should insert a nl here, put it into 3781590Srgrimes * the buffer */ 3791590Srgrimes force_nl = false; 3801590Srgrimes --line_no; /* this will be re-increased when the nl is 3811590Srgrimes * read from the buffer */ 3821590Srgrimes *sc_end++ = '\n'; 3831590Srgrimes *sc_end++ = ' '; 3841590Srgrimes if (verbose && !flushed_nl) /* print error msg if the line 3851590Srgrimes * was not already broken */ 38685632Sschweikh diag2(0, "Line broken"); 3871590Srgrimes flushed_nl = false; 3881590Srgrimes } 3891590Srgrimes for (t_ptr = token; *t_ptr; ++t_ptr) 3901590Srgrimes *sc_end++ = *t_ptr; /* copy token into temp buffer */ 3911590Srgrimes ps.procname[0] = 0; 3921590Srgrimes 3931590Srgrimes sw_buffer: 3941590Srgrimes ps.search_brace = false; /* stop looking for start of 3951590Srgrimes * stmt */ 3961590Srgrimes bp_save = buf_ptr; /* save current input buffer */ 3971590Srgrimes be_save = buf_end; 3981590Srgrimes buf_ptr = save_com; /* fix so that subsequent calls to 3991590Srgrimes * lexi will take tokens out of 4001590Srgrimes * save_com */ 4011590Srgrimes *sc_end++ = ' ';/* add trailing blank, just in case */ 4021590Srgrimes buf_end = sc_end; 4031590Srgrimes sc_end = 0; 4041590Srgrimes break; 4051590Srgrimes } /* end of switch */ 4061590Srgrimes if (type_code != 0) /* we must make this check, just in case there 4071590Srgrimes * was an unexpected EOF */ 4081590Srgrimes type_code = lexi(); /* read another token */ 4091590Srgrimes /* if (ps.search_brace) ps.procname[0] = 0; */ 4101590Srgrimes if ((is_procname = ps.procname[0]) && flushed_nl 4111590Srgrimes && !procnames_start_line && ps.in_decl 4121590Srgrimes && type_code == ident) 4131590Srgrimes flushed_nl = 0; 4141590Srgrimes } /* end of while (search_brace) */ 4151590Srgrimes last_else = 0; 4161590Srgrimescheck_type: 4171590Srgrimes if (type_code == 0) { /* we got eof */ 4181590Srgrimes if (s_lab != e_lab || s_code != e_code 4191590Srgrimes || s_com != e_com) /* must dump end of line */ 4201590Srgrimes dump_line(); 4211590Srgrimes if (ps.tos > 1) /* check for balanced braces */ 42285632Sschweikh diag2(1, "Stuff missing from end of file."); 4231590Srgrimes 4241590Srgrimes if (verbose) { 4251590Srgrimes printf("There were %d output lines and %d comments\n", 4261590Srgrimes ps.out_lines, ps.out_coms); 4271590Srgrimes printf("(Lines with comments)/(Lines with code): %6.3f\n", 4281590Srgrimes (1.0 * ps.com_lines) / code_lines); 4291590Srgrimes } 4301590Srgrimes fflush(output); 4311590Srgrimes exit(found_err); 4321590Srgrimes } 4331590Srgrimes if ( 4341590Srgrimes (type_code != comment) && 4351590Srgrimes (type_code != newline) && 4361590Srgrimes (type_code != preesc) && 4371590Srgrimes (type_code != form_feed)) { 4381590Srgrimes if (force_nl && 4391590Srgrimes (type_code != semicolon) && 4401590Srgrimes (type_code != lbrace || !btype_2)) { 4411590Srgrimes /* we should force a broken line here */ 4421590Srgrimes if (verbose && !flushed_nl) 44385632Sschweikh diag2(0, "Line broken"); 4441590Srgrimes flushed_nl = false; 4451590Srgrimes dump_line(); 4461590Srgrimes ps.want_blank = false; /* dont insert blank at line start */ 4471590Srgrimes force_nl = false; 4481590Srgrimes } 4491590Srgrimes ps.in_stmt = true; /* turn on flag which causes an extra level of 4501590Srgrimes * indentation. this is turned off by a ; or 4511590Srgrimes * '}' */ 4521590Srgrimes if (s_com != e_com) { /* the turkey has embedded a comment 4531590Srgrimes * in a line. fix it */ 4541590Srgrimes *e_code++ = ' '; 4551590Srgrimes for (t_ptr = s_com; *t_ptr; ++t_ptr) { 4561590Srgrimes CHECK_SIZE_CODE; 4571590Srgrimes *e_code++ = *t_ptr; 4581590Srgrimes } 4591590Srgrimes *e_code++ = ' '; 4601590Srgrimes *e_code = '\0'; /* null terminate code sect */ 4611590Srgrimes ps.want_blank = false; 4621590Srgrimes e_com = s_com; 4631590Srgrimes } 4641590Srgrimes } 4651590Srgrimes else if (type_code != comment) /* preserve force_nl thru a comment */ 4661590Srgrimes force_nl = false; /* cancel forced newline after newline, form 4671590Srgrimes * feed, etc */ 4681590Srgrimes 4691590Srgrimes 4701590Srgrimes 4711590Srgrimes /*-----------------------------------------------------*\ 4721590Srgrimes | do switch on type of token scanned | 4731590Srgrimes \*-----------------------------------------------------*/ 4741590Srgrimes CHECK_SIZE_CODE; 4751590Srgrimes switch (type_code) { /* now, decide what to do with the token */ 4761590Srgrimes 4771590Srgrimes case form_feed: /* found a form feed in line */ 4781590Srgrimes ps.use_ff = true; /* a form feed is treated much like a newline */ 4791590Srgrimes dump_line(); 4801590Srgrimes ps.want_blank = false; 4811590Srgrimes break; 4821590Srgrimes 4831590Srgrimes case newline: 4841590Srgrimes if (ps.last_token != comma || ps.p_l_follow > 0 4851590Srgrimes || !ps.leave_comma || ps.block_init || !break_comma || s_com != e_com) { 4861590Srgrimes dump_line(); 4871590Srgrimes ps.want_blank = false; 4881590Srgrimes } 4891590Srgrimes ++line_no; /* keep track of input line number */ 4901590Srgrimes break; 4911590Srgrimes 4921590Srgrimes case lparen: /* got a '(' or '[' */ 4931590Srgrimes ++ps.p_l_follow; /* count parens to make Healy happy */ 4941590Srgrimes if (ps.want_blank && *token != '[' && 4951590Srgrimes (ps.last_token != ident || proc_calls_space 4961590Srgrimes || (ps.its_a_keyword && (!ps.sizeof_keyword || Bill_Shannon)))) 4971590Srgrimes *e_code++ = ' '; 4981590Srgrimes if (ps.in_decl && !ps.block_init) 4991590Srgrimes if (troff && !ps.dumped_decl_indent && !is_procname && ps.last_token == decl) { 5001590Srgrimes ps.dumped_decl_indent = 1; 5011590Srgrimes sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); 5021590Srgrimes e_code += strlen(e_code); 5031590Srgrimes } 5041590Srgrimes else { 5051590Srgrimes while ((e_code - s_code) < dec_ind) { 5061590Srgrimes CHECK_SIZE_CODE; 5071590Srgrimes *e_code++ = ' '; 5081590Srgrimes } 5091590Srgrimes *e_code++ = token[0]; 5101590Srgrimes } 5111590Srgrimes else 5121590Srgrimes *e_code++ = token[0]; 5131590Srgrimes ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code; 5141590Srgrimes if (sp_sw && ps.p_l_follow == 1 && extra_expression_indent 5151590Srgrimes && ps.paren_indents[0] < 2 * ps.ind_size) 5161590Srgrimes ps.paren_indents[0] = 2 * ps.ind_size; 5171590Srgrimes ps.want_blank = false; 5181590Srgrimes if (ps.in_or_st && *token == '(' && ps.tos <= 2) { 5191590Srgrimes /* 5201590Srgrimes * this is a kluge to make sure that declarations will be 5211590Srgrimes * aligned right if proc decl has an explicit type on it, i.e. 5221590Srgrimes * "int a(x) {..." 5231590Srgrimes */ 5241590Srgrimes parse(semicolon); /* I said this was a kluge... */ 5251590Srgrimes ps.in_or_st = false; /* turn off flag for structure decl or 5261590Srgrimes * initialization */ 5271590Srgrimes } 5281590Srgrimes if (ps.sizeof_keyword) 5291590Srgrimes ps.sizeof_mask |= 1 << ps.p_l_follow; 5301590Srgrimes break; 5311590Srgrimes 5321590Srgrimes case rparen: /* got a ')' or ']' */ 5331590Srgrimes rparen_count--; 5341590Srgrimes if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask) { 5351590Srgrimes ps.last_u_d = true; 5361590Srgrimes ps.cast_mask &= (1 << ps.p_l_follow) - 1; 53769795Sobrien ps.want_blank = false; 53869795Sobrien } else 53969795Sobrien ps.want_blank = true; 5401590Srgrimes ps.sizeof_mask &= (1 << ps.p_l_follow) - 1; 5411590Srgrimes if (--ps.p_l_follow < 0) { 5421590Srgrimes ps.p_l_follow = 0; 54385632Sschweikh diag3(0, "Extra %c", *token); 5441590Srgrimes } 5451590Srgrimes if (e_code == s_code) /* if the paren starts the line */ 5461590Srgrimes ps.paren_level = ps.p_l_follow; /* then indent it */ 5471590Srgrimes 5481590Srgrimes *e_code++ = token[0]; 5491590Srgrimes 5501590Srgrimes if (sp_sw && (ps.p_l_follow == 0)) { /* check for end of if 5511590Srgrimes * (...), or some such */ 5521590Srgrimes sp_sw = false; 5531590Srgrimes force_nl = true;/* must force newline after if */ 5541590Srgrimes ps.last_u_d = true; /* inform lexi that a following 5551590Srgrimes * operator is unary */ 5561590Srgrimes ps.in_stmt = false; /* dont use stmt continuation 5571590Srgrimes * indentation */ 5581590Srgrimes 5591590Srgrimes parse(hd_type); /* let parser worry about if, or whatever */ 5601590Srgrimes } 5611590Srgrimes ps.search_brace = btype_2; /* this should insure that constructs 5621590Srgrimes * such as main(){...} and int[]{...} 5631590Srgrimes * have their braces put in the right 5641590Srgrimes * place */ 5651590Srgrimes break; 5661590Srgrimes 5671590Srgrimes case unary_op: /* this could be any unary operation */ 5681590Srgrimes if (ps.want_blank) 5691590Srgrimes *e_code++ = ' '; 5701590Srgrimes 5711590Srgrimes if (troff && !ps.dumped_decl_indent && ps.in_decl && !is_procname) { 5721590Srgrimes sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); 5731590Srgrimes ps.dumped_decl_indent = 1; 5741590Srgrimes e_code += strlen(e_code); 5751590Srgrimes } 5761590Srgrimes else { 57793440Sdwmalone const char *res = token; 5781590Srgrimes 5791590Srgrimes if (ps.in_decl && !ps.block_init) { /* if this is a unary op 5801590Srgrimes * in a declaration, we 5811590Srgrimes * should indent this 5821590Srgrimes * token */ 5831590Srgrimes for (i = 0; token[i]; ++i); /* find length of token */ 5841590Srgrimes while ((e_code - s_code) < (dec_ind - i)) { 5851590Srgrimes CHECK_SIZE_CODE; 5861590Srgrimes *e_code++ = ' '; /* pad it */ 5871590Srgrimes } 5881590Srgrimes } 5891590Srgrimes if (troff && token[0] == '-' && token[1] == '>') 5901590Srgrimes res = "\\(->"; 5911590Srgrimes for (t_ptr = res; *t_ptr; ++t_ptr) { 5921590Srgrimes CHECK_SIZE_CODE; 5931590Srgrimes *e_code++ = *t_ptr; 5941590Srgrimes } 5951590Srgrimes } 5961590Srgrimes ps.want_blank = false; 5971590Srgrimes break; 5981590Srgrimes 5991590Srgrimes case binary_op: /* any binary operation */ 6001590Srgrimes if (ps.want_blank) 6011590Srgrimes *e_code++ = ' '; 6021590Srgrimes { 60393440Sdwmalone const char *res = token; 6041590Srgrimes 6051590Srgrimes if (troff) 6061590Srgrimes switch (token[0]) { 6071590Srgrimes case '<': 6081590Srgrimes if (token[1] == '=') 6091590Srgrimes res = "\\(<="; 6101590Srgrimes break; 6111590Srgrimes case '>': 6121590Srgrimes if (token[1] == '=') 6131590Srgrimes res = "\\(>="; 6141590Srgrimes break; 6151590Srgrimes case '!': 6161590Srgrimes if (token[1] == '=') 6171590Srgrimes res = "\\(!="; 6181590Srgrimes break; 6191590Srgrimes case '|': 6201590Srgrimes if (token[1] == '|') 6211590Srgrimes res = "\\(br\\(br"; 6221590Srgrimes else if (token[1] == 0) 6231590Srgrimes res = "\\(br"; 6241590Srgrimes break; 6251590Srgrimes } 6261590Srgrimes for (t_ptr = res; *t_ptr; ++t_ptr) { 6271590Srgrimes CHECK_SIZE_CODE; 6281590Srgrimes *e_code++ = *t_ptr; /* move the operator */ 6291590Srgrimes } 6301590Srgrimes } 6311590Srgrimes ps.want_blank = true; 6321590Srgrimes break; 6331590Srgrimes 6341590Srgrimes case postop: /* got a trailing ++ or -- */ 6351590Srgrimes *e_code++ = token[0]; 6361590Srgrimes *e_code++ = token[1]; 6371590Srgrimes ps.want_blank = true; 6381590Srgrimes break; 6391590Srgrimes 6401590Srgrimes case question: /* got a ? */ 6411590Srgrimes squest++; /* this will be used when a later colon 6421590Srgrimes * appears so we can distinguish the 6431590Srgrimes * <c>?<n>:<n> construct */ 6441590Srgrimes if (ps.want_blank) 6451590Srgrimes *e_code++ = ' '; 6461590Srgrimes *e_code++ = '?'; 6471590Srgrimes ps.want_blank = true; 6481590Srgrimes break; 6491590Srgrimes 6501590Srgrimes case casestmt: /* got word 'case' or 'default' */ 6511590Srgrimes scase = true; /* so we can process the later colon properly */ 6521590Srgrimes goto copy_id; 6531590Srgrimes 6541590Srgrimes case colon: /* got a ':' */ 6551590Srgrimes if (squest > 0) { /* it is part of the <c>?<n>: <n> construct */ 6561590Srgrimes --squest; 6571590Srgrimes if (ps.want_blank) 6581590Srgrimes *e_code++ = ' '; 6591590Srgrimes *e_code++ = ':'; 6601590Srgrimes ps.want_blank = true; 6611590Srgrimes break; 6621590Srgrimes } 6631590Srgrimes if (ps.in_decl) { 6641590Srgrimes *e_code++ = ':'; 6651590Srgrimes ps.want_blank = false; 6661590Srgrimes break; 6671590Srgrimes } 6681590Srgrimes ps.in_stmt = false; /* seeing a label does not imply we are in a 6691590Srgrimes * stmt */ 6701590Srgrimes for (t_ptr = s_code; *t_ptr; ++t_ptr) 6711590Srgrimes *e_lab++ = *t_ptr; /* turn everything so far into a label */ 6721590Srgrimes e_code = s_code; 6731590Srgrimes *e_lab++ = ':'; 6741590Srgrimes *e_lab++ = ' '; 6751590Srgrimes *e_lab = '\0'; 6761590Srgrimes 6771590Srgrimes force_nl = ps.pcase = scase; /* ps.pcase will be used by 6781590Srgrimes * dump_line to decide how to 6791590Srgrimes * indent the label. force_nl 6801590Srgrimes * will force a case n: to be 6811590Srgrimes * on a line by itself */ 6821590Srgrimes scase = false; 6831590Srgrimes ps.want_blank = false; 6841590Srgrimes break; 6851590Srgrimes 6861590Srgrimes case semicolon: /* got a ';' */ 6871590Srgrimes ps.in_or_st = false;/* we are not in an initialization or 6881590Srgrimes * structure declaration */ 6891590Srgrimes scase = false; /* these will only need resetting in a error */ 6901590Srgrimes squest = 0; 6911590Srgrimes if (ps.last_token == rparen && rparen_count == 0) 6921590Srgrimes ps.in_parameter_declaration = 0; 6931590Srgrimes ps.cast_mask = 0; 6941590Srgrimes ps.sizeof_mask = 0; 6951590Srgrimes ps.block_init = 0; 6961590Srgrimes ps.block_init_level = 0; 6971590Srgrimes ps.just_saw_decl--; 6981590Srgrimes 6991590Srgrimes if (ps.in_decl && s_code == e_code && !ps.block_init) 7001590Srgrimes while ((e_code - s_code) < (dec_ind - 1)) { 7011590Srgrimes CHECK_SIZE_CODE; 7021590Srgrimes *e_code++ = ' '; 7031590Srgrimes } 7041590Srgrimes 7051590Srgrimes ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level 7061590Srgrimes * structure declaration, we 7071590Srgrimes * arent any more */ 7081590Srgrimes 7091590Srgrimes if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) { 7101590Srgrimes 7111590Srgrimes /* 7121590Srgrimes * This should be true iff there were unbalanced parens in the 7131590Srgrimes * stmt. It is a bit complicated, because the semicolon might 7141590Srgrimes * be in a for stmt 7151590Srgrimes */ 71685632Sschweikh diag2(1, "Unbalanced parens"); 7171590Srgrimes ps.p_l_follow = 0; 7181590Srgrimes if (sp_sw) { /* this is a check for a if, while, etc. with 7191590Srgrimes * unbalanced parens */ 7201590Srgrimes sp_sw = false; 7211590Srgrimes parse(hd_type); /* dont lose the if, or whatever */ 7221590Srgrimes } 7231590Srgrimes } 7241590Srgrimes *e_code++ = ';'; 7251590Srgrimes ps.want_blank = true; 7261590Srgrimes ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the 7271590Srgrimes * middle of a stmt */ 7281590Srgrimes 7291590Srgrimes if (!sp_sw) { /* if not if for (;;) */ 7301590Srgrimes parse(semicolon); /* let parser know about end of stmt */ 7311590Srgrimes force_nl = true;/* force newline after a end of stmt */ 7321590Srgrimes } 7331590Srgrimes break; 7341590Srgrimes 7351590Srgrimes case lbrace: /* got a '{' */ 7361590Srgrimes ps.in_stmt = false; /* dont indent the {} */ 7371590Srgrimes if (!ps.block_init) 7381590Srgrimes force_nl = true;/* force other stuff on same line as '{' onto 7391590Srgrimes * new line */ 7401590Srgrimes else if (ps.block_init_level <= 0) 7411590Srgrimes ps.block_init_level = 1; 7421590Srgrimes else 7431590Srgrimes ps.block_init_level++; 7441590Srgrimes 7451590Srgrimes if (s_code != e_code && !ps.block_init) { 7461590Srgrimes if (!btype_2) { 7471590Srgrimes dump_line(); 7481590Srgrimes ps.want_blank = false; 7491590Srgrimes } 7501590Srgrimes else if (ps.in_parameter_declaration && !ps.in_or_st) { 7511590Srgrimes ps.i_l_follow = 0; 7521590Srgrimes dump_line(); 7531590Srgrimes ps.want_blank = false; 7541590Srgrimes } 7551590Srgrimes } 7561590Srgrimes if (ps.in_parameter_declaration) 7571590Srgrimes prefix_blankline_requested = 0; 7581590Srgrimes 75972645Sasmodai if (ps.p_l_follow > 0) { /* check for preceding unbalanced 7601590Srgrimes * parens */ 76185632Sschweikh diag2(1, "Unbalanced parens"); 7621590Srgrimes ps.p_l_follow = 0; 7631590Srgrimes if (sp_sw) { /* check for unclosed if, for, etc. */ 7641590Srgrimes sp_sw = false; 7651590Srgrimes parse(hd_type); 7661590Srgrimes ps.ind_level = ps.i_l_follow; 7671590Srgrimes } 7681590Srgrimes } 7691590Srgrimes if (s_code == e_code) 7701590Srgrimes ps.ind_stmt = false; /* dont put extra indentation on line 7711590Srgrimes * with '{' */ 7721590Srgrimes if (ps.in_decl && ps.in_or_st) { /* this is either a structure 7731590Srgrimes * declaration or an init */ 7741590Srgrimes di_stack[ps.dec_nest++] = dec_ind; 7751590Srgrimes /* ? dec_ind = 0; */ 7761590Srgrimes } 7771590Srgrimes else { 7781590Srgrimes ps.decl_on_line = false; /* we cant be in the middle of 7791590Srgrimes * a declaration, so dont do 7801590Srgrimes * special indentation of 7811590Srgrimes * comments */ 7821590Srgrimes if (blanklines_after_declarations_at_proctop 7831590Srgrimes && ps.in_parameter_declaration) 7841590Srgrimes postfix_blankline_requested = 1; 7851590Srgrimes ps.in_parameter_declaration = 0; 7861590Srgrimes } 7871590Srgrimes dec_ind = 0; 7881590Srgrimes parse(lbrace); /* let parser know about this */ 7891590Srgrimes if (ps.want_blank) /* put a blank before '{' if '{' is not at 7901590Srgrimes * start of line */ 7911590Srgrimes *e_code++ = ' '; 7921590Srgrimes ps.want_blank = false; 7931590Srgrimes *e_code++ = '{'; 7941590Srgrimes ps.just_saw_decl = 0; 7951590Srgrimes break; 7961590Srgrimes 7971590Srgrimes case rbrace: /* got a '}' */ 7981590Srgrimes if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be 7991590Srgrimes * omitted in 8001590Srgrimes * declarations */ 8011590Srgrimes parse(semicolon); 8021590Srgrimes if (ps.p_l_follow) {/* check for unclosed if, for, else. */ 80385632Sschweikh diag2(1, "Unbalanced parens"); 8041590Srgrimes ps.p_l_follow = 0; 8051590Srgrimes sp_sw = false; 8061590Srgrimes } 8071590Srgrimes ps.just_saw_decl = 0; 8081590Srgrimes ps.block_init_level--; 8091590Srgrimes if (s_code != e_code && !ps.block_init) { /* '}' must be first on 8101590Srgrimes * line */ 8111590Srgrimes if (verbose) 81285632Sschweikh diag2(0, "Line broken"); 8131590Srgrimes dump_line(); 8141590Srgrimes } 8151590Srgrimes *e_code++ = '}'; 8161590Srgrimes ps.want_blank = true; 8171590Srgrimes ps.in_stmt = ps.ind_stmt = false; 8181590Srgrimes if (ps.dec_nest > 0) { /* we are in multi-level structure 8191590Srgrimes * declaration */ 8201590Srgrimes dec_ind = di_stack[--ps.dec_nest]; 8211590Srgrimes if (ps.dec_nest == 0 && !ps.in_parameter_declaration) 8221590Srgrimes ps.just_saw_decl = 2; 8231590Srgrimes ps.in_decl = true; 8241590Srgrimes } 8251590Srgrimes prefix_blankline_requested = 0; 8261590Srgrimes parse(rbrace); /* let parser know about this */ 8271590Srgrimes ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead 8281590Srgrimes && ps.il[ps.tos] >= ps.ind_level; 8291590Srgrimes if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0) 8301590Srgrimes postfix_blankline_requested = 1; 8311590Srgrimes break; 8321590Srgrimes 8331590Srgrimes case swstmt: /* got keyword "switch" */ 8341590Srgrimes sp_sw = true; 8351590Srgrimes hd_type = swstmt; /* keep this for when we have seen the 8361590Srgrimes * expression */ 8371590Srgrimes goto copy_id; /* go move the token into buffer */ 8381590Srgrimes 8391590Srgrimes case sp_paren: /* token is if, while, for */ 8401590Srgrimes sp_sw = true; /* the interesting stuff is done after the 8411590Srgrimes * expression is scanned */ 8421590Srgrimes hd_type = (*token == 'i' ? ifstmt : 8431590Srgrimes (*token == 'w' ? whilestmt : forstmt)); 8441590Srgrimes 8451590Srgrimes /* 8461590Srgrimes * remember the type of header for later use by parser 8471590Srgrimes */ 8481590Srgrimes goto copy_id; /* copy the token into line */ 8491590Srgrimes 8501590Srgrimes case sp_nparen: /* got else, do */ 8511590Srgrimes ps.in_stmt = false; 8521590Srgrimes if (*token == 'e') { 8531590Srgrimes if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) { 8541590Srgrimes if (verbose) 85585632Sschweikh diag2(0, "Line broken"); 8561590Srgrimes dump_line();/* make sure this starts a line */ 8571590Srgrimes ps.want_blank = false; 8581590Srgrimes } 8591590Srgrimes force_nl = true;/* also, following stuff must go onto new line */ 8601590Srgrimes last_else = 1; 8611590Srgrimes parse(elselit); 8621590Srgrimes } 8631590Srgrimes else { 8641590Srgrimes if (e_code != s_code) { /* make sure this starts a line */ 8651590Srgrimes if (verbose) 86685632Sschweikh diag2(0, "Line broken"); 8671590Srgrimes dump_line(); 8681590Srgrimes ps.want_blank = false; 8691590Srgrimes } 8701590Srgrimes force_nl = true;/* also, following stuff must go onto new line */ 8711590Srgrimes last_else = 0; 8721590Srgrimes parse(dolit); 8731590Srgrimes } 8741590Srgrimes goto copy_id; /* move the token into line */ 8751590Srgrimes 8761590Srgrimes case decl: /* we have a declaration type (int, register, 8771590Srgrimes * etc.) */ 8781590Srgrimes parse(decl); /* let parser worry about indentation */ 8791590Srgrimes if (ps.last_token == rparen && ps.tos <= 1) { 8801590Srgrimes ps.in_parameter_declaration = 1; 8811590Srgrimes if (s_code != e_code) { 8821590Srgrimes dump_line(); 8831590Srgrimes ps.want_blank = 0; 8841590Srgrimes } 8851590Srgrimes } 8861590Srgrimes if (ps.in_parameter_declaration && ps.indent_parameters && ps.dec_nest == 0) { 8871590Srgrimes ps.ind_level = ps.i_l_follow = 1; 8881590Srgrimes ps.ind_stmt = 0; 8891590Srgrimes } 8901590Srgrimes ps.in_or_st = true; /* this might be a structure or initialization 8911590Srgrimes * declaration */ 8921590Srgrimes ps.in_decl = ps.decl_on_line = true; 8931590Srgrimes if ( /* !ps.in_or_st && */ ps.dec_nest <= 0) 8941590Srgrimes ps.just_saw_decl = 2; 8951590Srgrimes prefix_blankline_requested = 0; 8961590Srgrimes for (i = 0; token[i++];); /* get length of token */ 8971590Srgrimes 8981590Srgrimes /* 8991590Srgrimes * dec_ind = e_code - s_code + (ps.decl_indent>i ? ps.decl_indent 9001590Srgrimes * : i); 9011590Srgrimes */ 9021590Srgrimes dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i; 9031590Srgrimes goto copy_id; 9041590Srgrimes 9051590Srgrimes case ident: /* got an identifier or constant */ 9061590Srgrimes if (ps.in_decl) { /* if we are in a declaration, we must indent 9071590Srgrimes * identifier */ 9081590Srgrimes if (ps.want_blank) 9091590Srgrimes *e_code++ = ' '; 9101590Srgrimes ps.want_blank = false; 9111590Srgrimes if (is_procname == 0 || !procnames_start_line) { 91285632Sschweikh if (!ps.block_init) { 9131590Srgrimes if (troff && !ps.dumped_decl_indent) { 9141590Srgrimes sprintf(e_code, "\n.De %dp+\200p\n", dec_ind * 7); 9151590Srgrimes ps.dumped_decl_indent = 1; 9161590Srgrimes e_code += strlen(e_code); 91785632Sschweikh } else { 9181590Srgrimes while ((e_code - s_code) < dec_ind) { 9191590Srgrimes CHECK_SIZE_CODE; 9201590Srgrimes *e_code++ = ' '; 9211590Srgrimes } 92285632Sschweikh } 92385632Sschweikh } 92485632Sschweikh } else { 9251590Srgrimes if (dec_ind && s_code != e_code) 9261590Srgrimes dump_line(); 9271590Srgrimes dec_ind = 0; 9281590Srgrimes ps.want_blank = false; 9291590Srgrimes } 9301590Srgrimes } 9311590Srgrimes else if (sp_sw && ps.p_l_follow == 0) { 9321590Srgrimes sp_sw = false; 9331590Srgrimes force_nl = true; 9341590Srgrimes ps.last_u_d = true; 9351590Srgrimes ps.in_stmt = false; 9361590Srgrimes parse(hd_type); 9371590Srgrimes } 9381590Srgrimes copy_id: 9391590Srgrimes if (ps.want_blank) 9401590Srgrimes *e_code++ = ' '; 9411590Srgrimes if (troff && ps.its_a_keyword) { 9421590Srgrimes e_code = chfont(&bodyf, &keywordf, e_code); 9431590Srgrimes for (t_ptr = token; *t_ptr; ++t_ptr) { 9441590Srgrimes CHECK_SIZE_CODE; 9451590Srgrimes *e_code++ = keywordf.allcaps && islower(*t_ptr) 9461590Srgrimes ? toupper(*t_ptr) : *t_ptr; 9471590Srgrimes } 9481590Srgrimes e_code = chfont(&keywordf, &bodyf, e_code); 9491590Srgrimes } 9501590Srgrimes else 9511590Srgrimes for (t_ptr = token; *t_ptr; ++t_ptr) { 9521590Srgrimes CHECK_SIZE_CODE; 9531590Srgrimes *e_code++ = *t_ptr; 9541590Srgrimes } 9551590Srgrimes ps.want_blank = true; 9561590Srgrimes break; 9571590Srgrimes 9581590Srgrimes case period: /* treat a period kind of like a binary 9591590Srgrimes * operation */ 9601590Srgrimes *e_code++ = '.'; /* move the period into line */ 9611590Srgrimes ps.want_blank = false; /* dont put a blank after a period */ 9621590Srgrimes break; 9631590Srgrimes 9641590Srgrimes case comma: 9651590Srgrimes ps.want_blank = (s_code != e_code); /* only put blank after comma 9661590Srgrimes * if comma does not start the 9671590Srgrimes * line */ 9681590Srgrimes if (ps.in_decl && is_procname == 0 && !ps.block_init) 9691590Srgrimes while ((e_code - s_code) < (dec_ind - 1)) { 9701590Srgrimes CHECK_SIZE_CODE; 9711590Srgrimes *e_code++ = ' '; 9721590Srgrimes } 9731590Srgrimes 9741590Srgrimes *e_code++ = ','; 9751590Srgrimes if (ps.p_l_follow == 0) { 9761590Srgrimes if (ps.block_init_level <= 0) 9771590Srgrimes ps.block_init = 0; 9781590Srgrimes if (break_comma && (!ps.leave_comma || compute_code_target() + (e_code - s_code) > max_col - 8)) 9791590Srgrimes force_nl = true; 9801590Srgrimes } 9811590Srgrimes break; 9821590Srgrimes 9831590Srgrimes case preesc: /* got the character '#' */ 9841590Srgrimes if ((s_com != e_com) || 9851590Srgrimes (s_lab != e_lab) || 9861590Srgrimes (s_code != e_code)) 9871590Srgrimes dump_line(); 9881590Srgrimes *e_lab++ = '#'; /* move whole line to 'label' buffer */ 9891590Srgrimes { 9901590Srgrimes int in_comment = 0; 9911590Srgrimes int com_start = 0; 9921590Srgrimes char quote = 0; 9931590Srgrimes int com_end = 0; 9941590Srgrimes 9951590Srgrimes while (*buf_ptr == ' ' || *buf_ptr == '\t') { 9961590Srgrimes buf_ptr++; 9971590Srgrimes if (buf_ptr >= buf_end) 9981590Srgrimes fill_buffer(); 9991590Srgrimes } 100073175Sobrien while (*buf_ptr != '\n' || (in_comment && !had_eof)) { 10011590Srgrimes CHECK_SIZE_LAB; 10021590Srgrimes *e_lab = *buf_ptr++; 10031590Srgrimes if (buf_ptr >= buf_end) 10041590Srgrimes fill_buffer(); 10051590Srgrimes switch (*e_lab++) { 10061590Srgrimes case BACKSLASH: 10071590Srgrimes if (troff) 10081590Srgrimes *e_lab++ = BACKSLASH; 10091590Srgrimes if (!in_comment) { 10101590Srgrimes *e_lab++ = *buf_ptr++; 10111590Srgrimes if (buf_ptr >= buf_end) 10121590Srgrimes fill_buffer(); 10131590Srgrimes } 10141590Srgrimes break; 10151590Srgrimes case '/': 10161590Srgrimes if (*buf_ptr == '*' && !in_comment && !quote) { 10171590Srgrimes in_comment = 1; 10181590Srgrimes *e_lab++ = *buf_ptr++; 10191590Srgrimes com_start = e_lab - s_lab - 2; 10201590Srgrimes } 10211590Srgrimes break; 10221590Srgrimes case '"': 10231590Srgrimes if (quote == '"') 10241590Srgrimes quote = 0; 10251590Srgrimes break; 10261590Srgrimes case '\'': 10271590Srgrimes if (quote == '\'') 10281590Srgrimes quote = 0; 10291590Srgrimes break; 10301590Srgrimes case '*': 10311590Srgrimes if (*buf_ptr == '/' && in_comment) { 10321590Srgrimes in_comment = 0; 10331590Srgrimes *e_lab++ = *buf_ptr++; 10341590Srgrimes com_end = e_lab - s_lab; 10351590Srgrimes } 10361590Srgrimes break; 10371590Srgrimes } 10381590Srgrimes } 10391590Srgrimes 10401590Srgrimes while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 10411590Srgrimes e_lab--; 10421590Srgrimes if (e_lab - s_lab == com_end && bp_save == 0) { /* comment on 10431590Srgrimes * preprocessor line */ 10441590Srgrimes if (sc_end == 0) /* if this is the first comment, we 10451590Srgrimes * must set up the buffer */ 10461590Srgrimes sc_end = &(save_com[0]); 10471590Srgrimes else { 10481590Srgrimes *sc_end++ = '\n'; /* add newline between 10491590Srgrimes * comments */ 10501590Srgrimes *sc_end++ = ' '; 10511590Srgrimes --line_no; 10521590Srgrimes } 10531590Srgrimes bcopy(s_lab + com_start, sc_end, com_end - com_start); 10541590Srgrimes sc_end += com_end - com_start; 10551590Srgrimes if (sc_end >= &save_com[sc_size]) 10561590Srgrimes abort(); 10571590Srgrimes e_lab = s_lab + com_start; 10581590Srgrimes while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 10591590Srgrimes e_lab--; 10601590Srgrimes bp_save = buf_ptr; /* save current input buffer */ 10611590Srgrimes be_save = buf_end; 10621590Srgrimes buf_ptr = save_com; /* fix so that subsequent calls to 10631590Srgrimes * lexi will take tokens out of 10641590Srgrimes * save_com */ 10651590Srgrimes *sc_end++ = ' '; /* add trailing blank, just in case */ 10661590Srgrimes buf_end = sc_end; 10671590Srgrimes sc_end = 0; 10681590Srgrimes } 10691590Srgrimes *e_lab = '\0'; /* null terminate line */ 10701590Srgrimes ps.pcase = false; 10711590Srgrimes } 10721590Srgrimes 10731590Srgrimes if (strncmp(s_lab, "#if", 3) == 0) { 10741590Srgrimes if (blanklines_around_conditional_compilation) { 107598771Sjmallett int c; 10761590Srgrimes prefix_blankline_requested++; 10771590Srgrimes while ((c = getc(input)) == '\n'); 10781590Srgrimes ungetc(c, input); 10791590Srgrimes } 108093440Sdwmalone if ((size_t)ifdef_level < sizeof(state_stack)/sizeof(state_stack[0])) { 10811590Srgrimes match_state[ifdef_level].tos = -1; 10821590Srgrimes state_stack[ifdef_level++] = ps; 10831590Srgrimes } 10841590Srgrimes else 108585632Sschweikh diag2(1, "#if stack overflow"); 10861590Srgrimes } 10871590Srgrimes else if (strncmp(s_lab, "#else", 5) == 0) 10881590Srgrimes if (ifdef_level <= 0) 108985632Sschweikh diag2(1, "Unmatched #else"); 10901590Srgrimes else { 10911590Srgrimes match_state[ifdef_level - 1] = ps; 10921590Srgrimes ps = state_stack[ifdef_level - 1]; 10931590Srgrimes } 10941590Srgrimes else if (strncmp(s_lab, "#endif", 6) == 0) { 10951590Srgrimes if (ifdef_level <= 0) 109685632Sschweikh diag2(1, "Unmatched #endif"); 10971590Srgrimes else { 10981590Srgrimes ifdef_level--; 10991590Srgrimes 11001590Srgrimes#ifdef undef 11011590Srgrimes /* 11021590Srgrimes * This match needs to be more intelligent before the 11031590Srgrimes * message is useful 11041590Srgrimes */ 11051590Srgrimes if (match_state[ifdef_level].tos >= 0 11061590Srgrimes && bcmp(&ps, &match_state[ifdef_level], sizeof ps)) 1107105244Scharnier diag2(0, "Syntactically inconsistent #ifdef alternatives."); 11081590Srgrimes#endif 11091590Srgrimes } 11101590Srgrimes if (blanklines_around_conditional_compilation) { 11111590Srgrimes postfix_blankline_requested++; 11121590Srgrimes n_real_blanklines = 0; 11131590Srgrimes } 11141590Srgrimes } 11151590Srgrimes break; /* subsequent processing of the newline 11161590Srgrimes * character will cause the line to be printed */ 11171590Srgrimes 111885632Sschweikh case comment: /* we have gotten a / followed by * this is a biggie */ 11191590Srgrimes if (flushed_nl) { /* we should force a broken line here */ 11201590Srgrimes flushed_nl = false; 11211590Srgrimes dump_line(); 11221590Srgrimes ps.want_blank = false; /* dont insert blank at line start */ 11231590Srgrimes force_nl = false; 11241590Srgrimes } 11251590Srgrimes pr_comment(); 11261590Srgrimes break; 11271590Srgrimes } /* end of big switch stmt */ 11281590Srgrimes 11291590Srgrimes *e_code = '\0'; /* make sure code section is null terminated */ 11301590Srgrimes if (type_code != comment && type_code != newline && type_code != preesc) 11311590Srgrimes ps.last_token = type_code; 11321590Srgrimes } /* end of main while (1) loop */ 11331590Srgrimes} 11341590Srgrimes 11351590Srgrimes/* 11361590Srgrimes * copy input file to backup file if in_name is /blah/blah/blah/file, then 11371590Srgrimes * backup file will be ".Bfile" then make the backup file the input and 11381590Srgrimes * original input file the output 11391590Srgrimes */ 114085632Sschweikhstatic void 114185632Sschweikhbakcopy(void) 11421590Srgrimes{ 11431590Srgrimes int n, 11441590Srgrimes bakchn; 11451590Srgrimes char buff[8 * 1024]; 114693440Sdwmalone const char *p; 11471590Srgrimes 11481590Srgrimes /* construct file name .Bfile */ 11491590Srgrimes for (p = in_name; *p; p++); /* skip to end of string */ 11501590Srgrimes while (p > in_name && *p != '/') /* find last '/' */ 11511590Srgrimes p--; 11521590Srgrimes if (*p == '/') 11531590Srgrimes p++; 11541590Srgrimes sprintf(bakfile, "%s.BAK", p); 11551590Srgrimes 11561590Srgrimes /* copy in_name to backup file */ 11571590Srgrimes bakchn = creat(bakfile, 0600); 11581590Srgrimes if (bakchn < 0) 115962894Skris err(1, "%s", bakfile); 116085632Sschweikh while ((n = read(fileno(input), buff, sizeof buff)) != 0) 11611590Srgrimes if (write(bakchn, buff, n) != n) 116262894Skris err(1, "%s", bakfile); 11631590Srgrimes if (n < 0) 116462894Skris err(1, "%s", in_name); 11651590Srgrimes close(bakchn); 11661590Srgrimes fclose(input); 11671590Srgrimes 11681590Srgrimes /* re-open backup file as the input file */ 11691590Srgrimes input = fopen(bakfile, "r"); 11701590Srgrimes if (input == 0) 117162894Skris err(1, "%s", bakfile); 11721590Srgrimes /* now the original input file will be the output */ 11731590Srgrimes output = fopen(in_name, "w"); 11741590Srgrimes if (output == 0) { 11751590Srgrimes unlink(bakfile); 117662894Skris err(1, "%s", in_name); 11771590Srgrimes } 11781590Srgrimes} 1179