121968Sdist /* 235500Sbostic * Copyright (c) 1985 Sun Microsystems, Inc. 335500Sbostic * Copyright (c) 1980 The Regents of the University of California. 433767Sbostic * Copyright (c) 1976 Board of Trustees of the University of Illinois. 533767Sbostic * All rights reserved. 633767Sbostic * 733767Sbostic * Redistribution and use in source and binary forms are permitted 834885Sbostic * provided that the above copyright notice and this paragraph are 934885Sbostic * duplicated in all such forms and that any documentation, 1034885Sbostic * advertising materials, and other materials related to such 1134885Sbostic * distribution and use acknowledge that the software was developed 1235500Sbostic * by the University of California, Berkeley, the University of Illinois, 1335500Sbostic * Urbana, and Sun Microsystems, Inc. The name of either University 1435500Sbostic * or Sun Microsystems may not be used to endorse or promote products 1535500Sbostic * derived from this software without specific prior written permission. 1634885Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1734885Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1834885Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1921968Sdist */ 208800Smckusick 2121968Sdist #ifndef lint 2221968Sdist char copyright[] = 2335500Sbostic "@(#) Copyright (c) 1985 Sun Microsystems, Inc.\n\ 2435500Sbostic @(#) Copyright (c) 1980 The Regents of the University of California.\n\ 2535500Sbostic @(#) Copyright (c) 1976 Board of Trustees of the University of Illinois.\n\ 2621968Sdist All rights reserved.\n"; 2733767Sbostic #endif /* not lint */ 2821968Sdist 2921968Sdist #ifndef lint 30*40275Sbostic static char sccsid[] = "@(#)indent.c 5.14 (Berkeley) 03/05/90"; 3133767Sbostic #endif /* not lint */ 3221968Sdist 3336970Sbostic #include <sys/param.h> 3435505Sbostic #include "indent_globs.h" 3535505Sbostic #include "indent_codes.h" 3635500Sbostic #include <ctype.h> 378800Smckusick 3835500Sbostic char *in_name = "Standard Input"; /* will always point to name of input 3935500Sbostic * file */ 4035500Sbostic char *out_name = "Standard Output"; /* will always point to name 4135500Sbostic * of output file */ 4235500Sbostic char bakfile[MAXPATHLEN] = ""; 438800Smckusick 4424453Smckusick main(argc, argv) 4524453Smckusick int argc; 4624453Smckusick char **argv; 478800Smckusick { 488800Smckusick 4935505Sbostic extern int found_err; /* flag set in diag() on error */ 5024453Smckusick int dec_ind; /* current indentation for declarations */ 5124453Smckusick int di_stack[20]; /* a stack of structure indentation levels */ 5235500Sbostic int flushed_nl; /* used when buffering up comments to remember 5335500Sbostic * that a newline was passed over */ 5424453Smckusick int force_nl; /* when true, code must be broken */ 5535500Sbostic int hd_type; /* used to store type of stmt for if (...), 5635500Sbostic * for (...), etc */ 5724453Smckusick register int i; /* local loop counter */ 5835500Sbostic int scase; /* set to true when we see a case, so we will 5935500Sbostic * know what to do with the following colon */ 6024453Smckusick int sp_sw; /* when true, we are in the expressin of 6124453Smckusick * if(...), while(...), etc. */ 6224453Smckusick int squest; /* when this is positive, we have seen a ? 6324453Smckusick * without the matching : in a <c>?<s>:<s> 6424453Smckusick * construct */ 6524453Smckusick register char *t_ptr; /* used for copying tokens */ 6624453Smckusick int type_code; /* the type of token, returned by lexi */ 678800Smckusick 6824453Smckusick int last_else = 0; /* true iff last keyword was an else */ 698800Smckusick 708800Smckusick 7124453Smckusick /*-----------------------------------------------*\ 7224648Smckusick | INITIALIZATION | 7324648Smckusick \*-----------------------------------------------*/ 748800Smckusick 758800Smckusick 7624453Smckusick ps.p_stack[0] = stmt; /* this is the parser's stack */ 7735500Sbostic ps.last_nl = true; /* this is true if the last thing scanned was 7835500Sbostic * a newline */ 7924453Smckusick ps.last_token = semicolon; 8035500Sbostic combuf = (char *) malloc(bufsize); 8135500Sbostic labbuf = (char *) malloc(bufsize); 8235500Sbostic codebuf = (char *) malloc(bufsize); 8338011Sbostic tokenbuf = (char *) malloc(bufsize); 8435500Sbostic l_com = combuf + bufsize - 5; 8535500Sbostic l_lab = labbuf + bufsize - 5; 8635500Sbostic l_code = codebuf + bufsize - 5; 8738011Sbostic l_token = tokenbuf + bufsize - 5; 8824453Smckusick combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and 8924453Smckusick * comment buffers */ 908800Smckusick combuf[1] = codebuf[1] = labbuf[1] = '\0'; 9135500Sbostic ps.else_if = 1; /* Default else-if special processing to on */ 928800Smckusick s_lab = e_lab = labbuf + 1; 938800Smckusick s_code = e_code = codebuf + 1; 948800Smckusick s_com = e_com = combuf + 1; 9538011Sbostic s_token = e_token = tokenbuf + 1; 968800Smckusick 9738011Sbostic in_buffer = (char *) malloc(10); 9838011Sbostic in_buffer_limit = in_buffer + 8; 998800Smckusick buf_ptr = buf_end = in_buffer; 1008800Smckusick line_no = 1; 10124453Smckusick had_eof = ps.in_decl = ps.decl_on_line = break_comma = false; 1028800Smckusick sp_sw = force_nl = false; 10324453Smckusick ps.in_or_st = false; 10424453Smckusick ps.bl_line = true; 1058800Smckusick dec_ind = 0; 10624453Smckusick di_stack[ps.dec_nest = 0] = 0; 10724453Smckusick ps.want_blank = ps.in_stmt = ps.ind_stmt = false; 1088800Smckusick 1098800Smckusick 11024453Smckusick scase = ps.pcase = false; 1118800Smckusick squest = 0; 1128800Smckusick sc_end = 0; 1138800Smckusick bp_save = 0; 1148800Smckusick be_save = 0; 1158800Smckusick 11624453Smckusick output = 0; 1178800Smckusick 1188800Smckusick 1198800Smckusick 12024453Smckusick /*--------------------------------------------------*\ 12135500Sbostic | COMMAND LINE SCAN | 12224648Smckusick \*--------------------------------------------------*/ 1238800Smckusick 12435500Sbostic #ifdef undef 12535500Sbostic max_col = 78; /* -l78 */ 12635500Sbostic lineup_to_parens = 1; /* -lp */ 12735500Sbostic ps.ljust_decl = 0; /* -ndj */ 12835500Sbostic ps.com_ind = 33; /* -c33 */ 12935500Sbostic star_comment_cont = 1; /* -sc */ 13035500Sbostic ps.ind_size = 8; /* -i8 */ 13135500Sbostic verbose = 0; 13235500Sbostic ps.decl_indent = 16; /* -di16 */ 13335500Sbostic ps.indent_parameters = 1; /* -ip */ 13435500Sbostic ps.decl_com_ind = 0; /* if this is not set to some positive value 13535500Sbostic * by an arg, we will set this equal to 13635500Sbostic * ps.com_ind */ 13735500Sbostic btype_2 = 1; /* -br */ 13835500Sbostic cuddle_else = 1; /* -ce */ 13935500Sbostic ps.unindent_displace = 0; /* -d0 */ 14035500Sbostic ps.case_indent = 0; /* -cli0 */ 14135500Sbostic format_col1_comments = 1; /* -fc1 */ 14235500Sbostic procnames_start_line = 1; /* -psl */ 14335500Sbostic proc_calls_space = 0; /* -npcs */ 14435500Sbostic comment_delimiter_on_blankline = 1; /* -cdb */ 14535500Sbostic ps.leave_comma = 1; /* -nbc */ 14635500Sbostic #endif 1478800Smckusick 14824453Smckusick for (i = 1; i < argc; ++i) 14924453Smckusick if (strcmp(argv[i], "-npro") == 0) 15024453Smckusick break; 15135500Sbostic set_defaults(); 15224453Smckusick if (i >= argc) 15324453Smckusick set_profile(); 1548800Smckusick 1558800Smckusick for (i = 1; i < argc; ++i) { 15624453Smckusick 15724453Smckusick /* 15835500Sbostic * look thru args (if any) for changes to defaults 15924453Smckusick */ 1608800Smckusick if (argv[i][0] != '-') {/* no flag on parameter */ 16124453Smckusick if (input == 0) { /* we must have the input file */ 16224453Smckusick in_name = argv[i]; /* remember name of input file */ 16324453Smckusick input = fopen(in_name, "r"); 16436970Sbostic if (input == 0) /* check for open error */ 16536970Sbostic err(in_name); 1668800Smckusick continue; 16735500Sbostic } 16835500Sbostic else if (output == 0) { /* we have the output file */ 16924453Smckusick out_name = argv[i]; /* remember name of output file */ 17024453Smckusick if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite 17124453Smckusick * the file */ 17224648Smckusick fprintf(stderr, "indent: input and output files must be different\n"); 17324648Smckusick exit(1); 17424453Smckusick } 17524453Smckusick output = fopen(out_name, "w"); 17636970Sbostic if (output == 0) /* check for create error */ 17736970Sbostic err(out_name); 17824453Smckusick continue; 1798800Smckusick } 18024648Smckusick fprintf(stderr, "indent: unknown parameter: %s\n", argv[i]); 18124648Smckusick exit(1); 18235500Sbostic } 18335500Sbostic else 18424453Smckusick set_option(argv[i]); 18524453Smckusick } /* end of for */ 18624453Smckusick if (input == 0) { 18735500Sbostic fprintf(stderr, "indent: usage: indent file [ outfile ] [ options ]\n"); 18824648Smckusick exit(1); 18924453Smckusick } 19024453Smckusick if (output == 0) 19124453Smckusick if (troff) 19224453Smckusick output = stdout; 19324453Smckusick else { 19424453Smckusick out_name = in_name; 19524453Smckusick bakcopy(); 1968800Smckusick } 19724453Smckusick if (ps.com_ind <= 1) 19835500Sbostic ps.com_ind = 2; /* dont put normal comments before column 2 */ 19935500Sbostic if (troff) { 20035500Sbostic if (bodyf.font[0] == 0) 20135500Sbostic parsefont(&bodyf, "R"); 20235500Sbostic if (scomf.font[0] == 0) 20335500Sbostic parsefont(&scomf, "I"); 20435500Sbostic if (blkcomf.font[0] == 0) 20535500Sbostic blkcomf = scomf, blkcomf.size += 2; 20635500Sbostic if (boxcomf.font[0] == 0) 20735500Sbostic boxcomf = blkcomf; 20835500Sbostic if (stringf.font[0] == 0) 20935500Sbostic parsefont(&stringf, "L"); 21035500Sbostic if (keywordf.font[0] == 0) 21135500Sbostic parsefont(&keywordf, "B"); 21235500Sbostic writefdef(&bodyf, 'B'); 21335500Sbostic writefdef(&scomf, 'C'); 21435500Sbostic writefdef(&blkcomf, 'L'); 21535500Sbostic writefdef(&boxcomf, 'X'); 21635500Sbostic writefdef(&stringf, 'S'); 21735500Sbostic writefdef(&keywordf, 'K'); 21835500Sbostic } 21924453Smckusick if (block_comment_max_col <= 0) 22024453Smckusick block_comment_max_col = max_col; 22124453Smckusick if (ps.decl_com_ind <= 0) /* if not specified by user, set this */ 22235500Sbostic ps.decl_com_ind = ps.ljust_decl ? (ps.com_ind <= 10 ? 2 : ps.com_ind - 8) : ps.com_ind; 22324453Smckusick if (continuation_indent == 0) 22424453Smckusick continuation_indent = ps.ind_size; 22535500Sbostic fill_buffer(); /* get first batch of stuff into input buffer */ 2268800Smckusick 22724453Smckusick parse(semicolon); 22824453Smckusick { 22924453Smckusick register char *p = buf_ptr; 23024453Smckusick register col = 1; 2318800Smckusick 23224453Smckusick while (1) { 23324453Smckusick if (*p == ' ') 23424453Smckusick col++; 23524453Smckusick else if (*p == '\t') 23624453Smckusick col = ((col - 1) & ~7) + 9; 23724453Smckusick else 23824453Smckusick break; 23924453Smckusick p++; 24036970Sbostic } 24124453Smckusick if (col > ps.ind_size) 24224453Smckusick ps.ind_level = ps.i_l_follow = col / ps.ind_size; 2438800Smckusick } 24424453Smckusick if (troff) { 24524453Smckusick register char *p = in_name, 24624453Smckusick *beg = in_name; 24724453Smckusick 24824453Smckusick while (*p) 24924453Smckusick if (*p++ == '/') 25024453Smckusick beg = p; 25124453Smckusick fprintf(output, ".Fn \"%s\"\n", beg); 2528800Smckusick } 25324453Smckusick /* 25435500Sbostic * START OF MAIN LOOP 25524453Smckusick */ 2568800Smckusick 25735500Sbostic while (1) { /* this is the main loop. it will go until we 25835500Sbostic * reach eof */ 25924453Smckusick int is_procname; 2608800Smckusick 26124453Smckusick type_code = lexi(); /* lexi reads one token. The actual 26235500Sbostic * characters read are stored in "token". lexi 26335500Sbostic * returns a code indicating the type of token */ 26424453Smckusick is_procname = ps.procname[0]; 2658800Smckusick 26624453Smckusick /* 26735500Sbostic * The following code moves everything following an if (), while (), 26835500Sbostic * else, etc. up to the start of the following stmt to a buffer. This 26935500Sbostic * allows proper handling of both kinds of brace placement. 27024453Smckusick */ 2718800Smckusick 2728800Smckusick flushed_nl = false; 27324453Smckusick while (ps.search_brace) { /* if we scanned an if(), while(), 27435500Sbostic * etc., we might need to copy stuff 27535500Sbostic * into a buffer we must loop, copying 27635500Sbostic * stuff into save_com, until we find 27735500Sbostic * the start of the stmt which follows 27824453Smckusick * the if, or whatever */ 2798800Smckusick switch (type_code) { 28035500Sbostic case newline: 28135500Sbostic ++line_no; 28235500Sbostic flushed_nl = true; 28335500Sbostic case form_feed: 28435500Sbostic break; /* form feeds and newlines found here will be 28535500Sbostic * ignored */ 2868800Smckusick 28735500Sbostic case lbrace: /* this is a brace that starts the compound 28835500Sbostic * stmt */ 28935500Sbostic if (sc_end == 0) { /* ignore buffering if a comment wasnt 29035500Sbostic * stored up */ 29135500Sbostic ps.search_brace = false; 29235500Sbostic goto check_type; 29335500Sbostic } 29435500Sbostic if (btype_2) { 29535500Sbostic save_com[0] = '{'; /* we either want to put the brace 29635500Sbostic * right after the if */ 29735500Sbostic goto sw_buffer; /* go to common code to get out of 29824453Smckusick * this loop */ 29935500Sbostic } 30035500Sbostic case comment: /* we have a comment, so we must copy it into 30135500Sbostic * the buffer */ 30235500Sbostic if (!flushed_nl || sc_end != 0) { 30335500Sbostic if (sc_end == 0) { /* if this is the first comment, we 30435500Sbostic * must set up the buffer */ 30535500Sbostic save_com[0] = save_com[1] = ' '; 30635500Sbostic sc_end = &(save_com[2]); 3078800Smckusick } 30835500Sbostic else { 30935500Sbostic *sc_end++ = '\n'; /* add newline between 31024453Smckusick * comments */ 31135500Sbostic *sc_end++ = ' '; 31235500Sbostic --line_no; 31335500Sbostic } 31435500Sbostic *sc_end++ = '/'; /* copy in start of comment */ 31535500Sbostic *sc_end++ = '*'; 3168800Smckusick 31735500Sbostic for (;;) { /* loop until we get to the end of the comment */ 31835500Sbostic *sc_end = *buf_ptr++; 31935500Sbostic if (buf_ptr >= buf_end) 32035500Sbostic fill_buffer(); 32124453Smckusick 32235500Sbostic if (*sc_end++ == '*' && *buf_ptr == '/') 32335500Sbostic break; /* we are at end of comment */ 32424453Smckusick 32535500Sbostic if (sc_end >= &(save_com[sc_size])) { /* check for temp buffer 32635500Sbostic * overflow */ 32735500Sbostic diag(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever."); 32835500Sbostic fflush(output); 32935500Sbostic exit(1); 33024453Smckusick } 33124453Smckusick } 33235500Sbostic *sc_end++ = '/'; /* add ending slash */ 33335500Sbostic if (++buf_ptr >= buf_end) /* get past / in buffer */ 33435500Sbostic fill_buffer(); 33535500Sbostic break; 33635500Sbostic } 33735500Sbostic default: /* it is the start of a normal statment */ 33835500Sbostic if (flushed_nl) /* if we flushed a newline, make sure it is 33935500Sbostic * put back */ 34035500Sbostic force_nl = true; 34135500Sbostic if (type_code == sp_paren && *token == 'i' 34224453Smckusick && last_else && ps.else_if 34324453Smckusick || type_code == sp_nparen && *token == 'e' 34424453Smckusick && e_code != s_code && e_code[-1] == '}') 34535500Sbostic force_nl = false; 3468800Smckusick 34735500Sbostic if (sc_end == 0) { /* ignore buffering if comment wasnt 34835500Sbostic * saved up */ 34935500Sbostic ps.search_brace = false; 35035500Sbostic goto check_type; 35135500Sbostic } 35235500Sbostic if (force_nl) { /* if we should insert a nl here, put it into 35335500Sbostic * the buffer */ 35435500Sbostic force_nl = false; 35535500Sbostic --line_no; /* this will be re-increased when the nl is 35635500Sbostic * read from the buffer */ 35735500Sbostic *sc_end++ = '\n'; 35835500Sbostic *sc_end++ = ' '; 35935500Sbostic if (verbose && !flushed_nl) /* print error msg if the line 36035500Sbostic * was not already broken */ 36135500Sbostic diag(0, "Line broken"); 36235500Sbostic flushed_nl = false; 36335500Sbostic } 36435500Sbostic for (t_ptr = token; *t_ptr; ++t_ptr) 36535500Sbostic *sc_end++ = *t_ptr; /* copy token into temp buffer */ 36635500Sbostic ps.procname[0] = 0; 3678800Smckusick 36835500Sbostic sw_buffer: 36935500Sbostic ps.search_brace = false; /* stop looking for start of 37035500Sbostic * stmt */ 37135500Sbostic bp_save = buf_ptr; /* save current input buffer */ 37235500Sbostic be_save = buf_end; 37335500Sbostic buf_ptr = save_com; /* fix so that subsequent calls to 37424453Smckusick * lexi will take tokens out of 37524453Smckusick * save_com */ 37635500Sbostic *sc_end++ = ' ';/* add trailing blank, just in case */ 37735500Sbostic buf_end = sc_end; 37835500Sbostic sc_end = 0; 37935500Sbostic break; 38024453Smckusick } /* end of switch */ 38135500Sbostic if (type_code != 0) /* we must make this check, just in case there 38235500Sbostic * was an unexpected EOF */ 38324453Smckusick type_code = lexi(); /* read another token */ 38435500Sbostic /* if (ps.search_brace) ps.procname[0] = 0; */ 38535500Sbostic if ((is_procname = ps.procname[0]) && flushed_nl 38635500Sbostic && !procnames_start_line && ps.in_decl 38735500Sbostic && type_code == ident) 38835500Sbostic flushed_nl = 0; 38935500Sbostic } /* end of while (search_brace) */ 39024453Smckusick last_else = 0; 39124453Smckusick check_type: 39224453Smckusick if (type_code == 0) { /* we got eof */ 3938800Smckusick if (s_lab != e_lab || s_code != e_code 39435500Sbostic || s_com != e_com) /* must dump end of line */ 39524453Smckusick dump_line(); 39624453Smckusick if (ps.tos > 1) /* check for balanced braces */ 39724453Smckusick diag(1, "Stuff missing from end of file."); 3988800Smckusick 3998800Smckusick if (verbose) { 40024453Smckusick printf("There were %d output lines and %d comments\n", 40124453Smckusick ps.out_lines, ps.out_coms); 40224453Smckusick printf("(Lines with comments)/(Lines with code): %6.3f\n", 40324453Smckusick (1.0 * ps.com_lines) / code_lines); 4048800Smckusick } 40524453Smckusick fflush(output); 40635505Sbostic exit(found_err); 4078800Smckusick } 4088800Smckusick if ( 40935500Sbostic (type_code != comment) && 41035500Sbostic (type_code != newline) && 41135500Sbostic (type_code != preesc) && 41235500Sbostic (type_code != form_feed)) { 41335500Sbostic if (force_nl && 41435500Sbostic (type_code != semicolon) && 41535500Sbostic (type_code != lbrace || !btype_2)) { 41635500Sbostic /* we should force a broken line here */ 4178800Smckusick if (verbose && !flushed_nl) 41824453Smckusick diag(0, "Line broken"); 4198800Smckusick flushed_nl = false; 42024453Smckusick dump_line(); 42124453Smckusick ps.want_blank = false; /* dont insert blank at line start */ 4228800Smckusick force_nl = false; 4238800Smckusick } 42435500Sbostic ps.in_stmt = true; /* turn on flag which causes an extra level of 42535500Sbostic * indentation. this is turned off by a ; or 42635500Sbostic * '}' */ 42735500Sbostic if (s_com != e_com) { /* the turkey has embedded a comment 42835500Sbostic * in a line. fix it */ 4298800Smckusick *e_code++ = ' '; 43035500Sbostic for (t_ptr = s_com; *t_ptr; ++t_ptr) { 431*40275Sbostic CHECK_SIZE_CODE; 4328800Smckusick *e_code++ = *t_ptr; 43335500Sbostic } 4348800Smckusick *e_code++ = ' '; 43524453Smckusick *e_code = '\0'; /* null terminate code sect */ 43624453Smckusick ps.want_blank = false; 4378800Smckusick e_com = s_com; 4388800Smckusick } 43935500Sbostic } 44035500Sbostic else if (type_code != comment) /* preserve force_nl thru a comment */ 44135500Sbostic force_nl = false; /* cancel forced newline after newline, form 44235500Sbostic * feed, etc */ 4438800Smckusick 4448800Smckusick 4458800Smckusick 44635500Sbostic /*-----------------------------------------------------*\ 44735500Sbostic | do switch on type of token scanned | 44835500Sbostic \*-----------------------------------------------------*/ 449*40275Sbostic CHECK_SIZE_CODE; 45024453Smckusick switch (type_code) { /* now, decide what to do with the token */ 45124453Smckusick 45235500Sbostic case form_feed: /* found a form feed in line */ 45335500Sbostic ps.use_ff = true; /* a form feed is treated much like a newline */ 45435500Sbostic dump_line(); 45535500Sbostic ps.want_blank = false; 45635500Sbostic break; 45735500Sbostic 45835500Sbostic case newline: 45935500Sbostic if (ps.last_token != comma || ps.p_l_follow > 0 46035500Sbostic || !ps.leave_comma || ps.block_init || !break_comma || s_com != e_com) { 46124453Smckusick dump_line(); 46224453Smckusick ps.want_blank = false; 46335500Sbostic } 46435500Sbostic ++line_no; /* keep track of input line number */ 46535500Sbostic break; 4668800Smckusick 46735500Sbostic case lparen: /* got a '(' or '[' */ 46835500Sbostic ++ps.p_l_follow; /* count parens to make Healy happy */ 46935500Sbostic if (ps.want_blank && *token != '[' && 47035500Sbostic (ps.last_token != ident || proc_calls_space 47135500Sbostic || (ps.its_a_keyword && (!ps.sizeof_keyword || Bill_Shannon)))) 47235500Sbostic *e_code++ = ' '; 47335500Sbostic if (ps.in_decl && !ps.block_init) 47435500Sbostic if (troff && !ps.dumped_decl_indent && !is_procname && ps.last_token == decl) { 47535500Sbostic ps.dumped_decl_indent = 1; 47635500Sbostic sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); 47735500Sbostic e_code += strlen(e_code); 47824453Smckusick } 47935500Sbostic else { 48035500Sbostic while ((e_code - s_code) < dec_ind) { 481*40275Sbostic CHECK_SIZE_CODE; 48235500Sbostic *e_code++ = ' '; 48335500Sbostic } 48424453Smckusick *e_code++ = token[0]; 4858800Smckusick } 48635500Sbostic else 48735500Sbostic *e_code++ = token[0]; 48835500Sbostic ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code; 48935500Sbostic if (sp_sw && ps.p_l_follow == 1 && extra_expression_indent 49035500Sbostic && ps.paren_indents[0] < 2 * ps.ind_size) 49135500Sbostic ps.paren_indents[0] = 2 * ps.ind_size; 49235500Sbostic ps.want_blank = false; 49335500Sbostic if (ps.in_or_st && *token == '(' && ps.tos <= 2) { 49435500Sbostic /* 49535500Sbostic * this is a kluge to make sure that declarations will be 49635500Sbostic * aligned right if proc decl has an explicit type on it, i.e. 49735500Sbostic * "int a(x) {..." 49835500Sbostic */ 49935500Sbostic parse(semicolon); /* I said this was a kluge... */ 50035500Sbostic ps.in_or_st = false; /* turn off flag for structure decl or 50135500Sbostic * initialization */ 50235500Sbostic } 50335500Sbostic if (ps.sizeof_keyword) 50435500Sbostic ps.sizeof_mask |= 1 << ps.p_l_follow; 50535500Sbostic break; 5068800Smckusick 50735500Sbostic case rparen: /* got a ')' or ']' */ 50838011Sbostic rparen_count--; 50935500Sbostic if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask) { 51035500Sbostic ps.last_u_d = true; 51135500Sbostic ps.cast_mask &= (1 << ps.p_l_follow) - 1; 51235500Sbostic } 51335500Sbostic ps.sizeof_mask &= (1 << ps.p_l_follow) - 1; 51435500Sbostic if (--ps.p_l_follow < 0) { 51535500Sbostic ps.p_l_follow = 0; 51635500Sbostic diag(0, "Extra %c", *token); 51735500Sbostic } 51835500Sbostic if (e_code == s_code) /* if the paren starts the line */ 51935500Sbostic ps.paren_level = ps.p_l_follow; /* then indent it */ 5208800Smckusick 52135500Sbostic *e_code++ = token[0]; 52235500Sbostic ps.want_blank = true; 5238800Smckusick 52435500Sbostic if (sp_sw && (ps.p_l_follow == 0)) { /* check for end of if 52524453Smckusick * (...), or some such */ 52635500Sbostic sp_sw = false; 52735500Sbostic force_nl = true;/* must force newline after if */ 52835500Sbostic ps.last_u_d = true; /* inform lexi that a following 52924453Smckusick * operator is unary */ 53035500Sbostic ps.in_stmt = false; /* dont use stmt continuation 53124453Smckusick * indentation */ 5328800Smckusick 53335500Sbostic parse(hd_type); /* let parser worry about if, or whatever */ 53435500Sbostic } 53535500Sbostic ps.search_brace = btype_2; /* this should insure that constructs 53635500Sbostic * such as main(){...} and int[]{...} 53735500Sbostic * have their braces put in the right 53835500Sbostic * place */ 53935500Sbostic break; 5408800Smckusick 54135500Sbostic case unary_op: /* this could be any unary operation */ 54235500Sbostic if (ps.want_blank) 54335500Sbostic *e_code++ = ' '; 5448800Smckusick 54535500Sbostic if (troff && !ps.dumped_decl_indent && ps.in_decl && !is_procname) { 54635500Sbostic sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); 54735500Sbostic ps.dumped_decl_indent = 1; 54835500Sbostic e_code += strlen(e_code); 54935500Sbostic } 55035500Sbostic else { 55135500Sbostic char *res = token; 55224453Smckusick 55335500Sbostic if (ps.in_decl && !ps.block_init) { /* if this is a unary op 55424453Smckusick * in a declaration, we 55524453Smckusick * should indent this 55624453Smckusick * token */ 55735500Sbostic for (i = 0; token[i]; ++i); /* find length of token */ 55835500Sbostic while ((e_code - s_code) < (dec_ind - i)) { 559*40275Sbostic CHECK_SIZE_CODE; 56035500Sbostic *e_code++ = ' '; /* pad it */ 56124453Smckusick } 5628800Smckusick } 56335500Sbostic if (troff && token[0] == '-' && token[1] == '>') 56435500Sbostic res = "\\(->"; 56535500Sbostic for (t_ptr = res; *t_ptr; ++t_ptr) { 566*40275Sbostic CHECK_SIZE_CODE; 56735500Sbostic *e_code++ = *t_ptr; 56835500Sbostic } 56935500Sbostic } 57035500Sbostic ps.want_blank = false; 57135500Sbostic break; 5728800Smckusick 57335500Sbostic case binary_op: /* any binary operation */ 57435500Sbostic if (ps.want_blank) 57535500Sbostic *e_code++ = ' '; 57635500Sbostic { 57735500Sbostic char *res = token; 57824453Smckusick 57935500Sbostic if (troff) 58035500Sbostic switch (token[0]) { 58135500Sbostic case '<': 58235500Sbostic if (token[1] == '=') 58335500Sbostic res = "\\(<="; 58435500Sbostic break; 58535500Sbostic case '>': 58635500Sbostic if (token[1] == '=') 58735500Sbostic res = "\\(>="; 58835500Sbostic break; 58935500Sbostic case '!': 59035500Sbostic if (token[1] == '=') 59135500Sbostic res = "\\(!="; 59235500Sbostic break; 59335500Sbostic case '|': 59435500Sbostic if (token[1] == '|') 59535500Sbostic res = "\\(br\\(br"; 59635500Sbostic else if (token[1] == 0) 59735500Sbostic res = "\\(br"; 59835500Sbostic break; 59935500Sbostic } 60035500Sbostic for (t_ptr = res; *t_ptr; ++t_ptr) { 601*40275Sbostic CHECK_SIZE_CODE; 60235500Sbostic *e_code++ = *t_ptr; /* move the operator */ 60324453Smckusick } 60435500Sbostic } 60535500Sbostic ps.want_blank = true; 60635500Sbostic break; 6078800Smckusick 60835500Sbostic case postop: /* got a trailing ++ or -- */ 60935500Sbostic *e_code++ = token[0]; 61035500Sbostic *e_code++ = token[1]; 61135500Sbostic ps.want_blank = true; 61235500Sbostic break; 6138800Smckusick 61435500Sbostic case question: /* got a ? */ 61535500Sbostic squest++; /* this will be used when a later colon 61624453Smckusick * appears so we can distinguish the 61724453Smckusick * <c>?<n>:<n> construct */ 61835500Sbostic if (ps.want_blank) 61935500Sbostic *e_code++ = ' '; 62035500Sbostic *e_code++ = '?'; 62135500Sbostic ps.want_blank = true; 62235500Sbostic break; 62335500Sbostic 62435500Sbostic case casestmt: /* got word 'case' or 'default' */ 62535500Sbostic scase = true; /* so we can process the later colon properly */ 62635500Sbostic goto copy_id; 62735500Sbostic 62835500Sbostic case colon: /* got a ':' */ 62935500Sbostic if (squest > 0) { /* it is part of the <c>?<n>: <n> construct */ 63035500Sbostic --squest; 63124453Smckusick if (ps.want_blank) 6328800Smckusick *e_code++ = ' '; 63335500Sbostic *e_code++ = ':'; 63424453Smckusick ps.want_blank = true; 6358800Smckusick break; 63635500Sbostic } 63735500Sbostic if (ps.in_decl) { 63835500Sbostic *e_code++ = ':'; 63924453Smckusick ps.want_blank = false; 6408800Smckusick break; 64135500Sbostic } 64235500Sbostic ps.in_stmt = false; /* seeing a label does not imply we are in a 64335500Sbostic * stmt */ 64435500Sbostic for (t_ptr = s_code; *t_ptr; ++t_ptr) 64535500Sbostic *e_lab++ = *t_ptr; /* turn everything so far into a label */ 64635500Sbostic e_code = s_code; 64735500Sbostic *e_lab++ = ':'; 64835500Sbostic *e_lab++ = ' '; 64935500Sbostic *e_lab = '\0'; 6508800Smckusick 65135500Sbostic force_nl = ps.pcase = scase; /* ps.pcase will be used by 65235500Sbostic * dump_line to decide how to 65335500Sbostic * indent the label. force_nl 65435500Sbostic * will force a case n: to be 65535500Sbostic * on a line by itself */ 65635500Sbostic scase = false; 65735500Sbostic ps.want_blank = false; 65835500Sbostic break; 6598800Smckusick 66035500Sbostic case semicolon: /* got a ';' */ 66135500Sbostic ps.in_or_st = false;/* we are not in an initialization or 66235500Sbostic * structure declaration */ 66335500Sbostic scase = false; /* these will only need resetting in a error */ 66435500Sbostic squest = 0; 66538011Sbostic if (ps.last_token == rparen && rparen_count == 0) 66635500Sbostic ps.in_parameter_declaration = 0; 66735500Sbostic ps.cast_mask = 0; 66835500Sbostic ps.sizeof_mask = 0; 66935500Sbostic ps.block_init = 0; 67035500Sbostic ps.block_init_level = 0; 67135500Sbostic ps.just_saw_decl--; 6728800Smckusick 67335500Sbostic if (ps.in_decl && s_code == e_code && !ps.block_init) 67435500Sbostic while ((e_code - s_code) < (dec_ind - 1)) { 675*40275Sbostic CHECK_SIZE_CODE; 67635500Sbostic *e_code++ = ' '; 67735500Sbostic } 6788800Smckusick 67935500Sbostic ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level 68035500Sbostic * structure declaration, we 68135500Sbostic * arent any more */ 68224453Smckusick 68335500Sbostic if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) { 6848800Smckusick 68535500Sbostic /* 68635500Sbostic * This should be true iff there were unbalanced parens in the 68735500Sbostic * stmt. It is a bit complicated, because the semicolon might 68835500Sbostic * be in a for stmt 68935500Sbostic */ 69035500Sbostic diag(1, "Unbalanced parens"); 69135500Sbostic ps.p_l_follow = 0; 69235500Sbostic if (sp_sw) { /* this is a check for a if, while, etc. with 69335500Sbostic * unbalanced parens */ 69435500Sbostic sp_sw = false; 69535500Sbostic parse(hd_type); /* dont lose the if, or whatever */ 6968800Smckusick } 69735500Sbostic } 69835500Sbostic *e_code++ = ';'; 69935500Sbostic ps.want_blank = true; 70035500Sbostic ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the 70135500Sbostic * middle of a stmt */ 7028800Smckusick 70335500Sbostic if (!sp_sw) { /* if not if for (;;) */ 70435500Sbostic parse(semicolon); /* let parser know about end of stmt */ 70535500Sbostic force_nl = true;/* force newline after a end of stmt */ 70635500Sbostic } 70735500Sbostic break; 7088800Smckusick 70935500Sbostic case lbrace: /* got a '{' */ 71035500Sbostic ps.in_stmt = false; /* dont indent the {} */ 71135500Sbostic if (!ps.block_init) 71235500Sbostic force_nl = true;/* force other stuff on same line as '{' onto 71335500Sbostic * new line */ 71435500Sbostic else if (ps.block_init_level <= 0) 71535500Sbostic ps.block_init_level = 1; 71635500Sbostic else 71735500Sbostic ps.block_init_level++; 7188800Smckusick 71935500Sbostic if (s_code != e_code && !ps.block_init) { 72035500Sbostic if (!btype_2) { 72135500Sbostic dump_line(); 72235500Sbostic ps.want_blank = false; 7238800Smckusick } 72435500Sbostic else if (ps.in_parameter_declaration && !ps.in_or_st) { 72535500Sbostic ps.i_l_follow = 0; 72635500Sbostic dump_line(); 72735500Sbostic ps.want_blank = false; 7288800Smckusick } 72935500Sbostic } 73035500Sbostic if (ps.in_parameter_declaration) 73135500Sbostic prefix_blankline_requested = 0; 7328800Smckusick 73335500Sbostic if (ps.p_l_follow > 0) { /* check for preceeding unbalanced 73435500Sbostic * parens */ 73535500Sbostic diag(1, "Unbalanced parens"); 73635500Sbostic ps.p_l_follow = 0; 73735500Sbostic if (sp_sw) { /* check for unclosed if, for, etc. */ 7388800Smckusick sp_sw = false; 73935500Sbostic parse(hd_type); 74035500Sbostic ps.ind_level = ps.i_l_follow; 7418800Smckusick } 74235500Sbostic } 74335500Sbostic if (s_code == e_code) 74435500Sbostic ps.ind_stmt = false; /* dont put extra indentation on line 74535500Sbostic * with '{' */ 74635500Sbostic if (ps.in_decl && ps.in_or_st) { /* this is either a structure 74735500Sbostic * declaration or an init */ 74835500Sbostic di_stack[ps.dec_nest++] = dec_ind; 74935500Sbostic /* ? dec_ind = 0; */ 75035500Sbostic } 75135500Sbostic else { 75235500Sbostic ps.decl_on_line = false; /* we cant be in the middle of 75335500Sbostic * a declaration, so dont do 75435500Sbostic * special indentation of 75535500Sbostic * comments */ 75635500Sbostic if (blanklines_after_declarations_at_proctop 75735500Sbostic && ps.in_parameter_declaration) 75824453Smckusick postfix_blankline_requested = 1; 75935500Sbostic ps.in_parameter_declaration = 0; 76035500Sbostic } 76135500Sbostic dec_ind = 0; 76235500Sbostic parse(lbrace); /* let parser know about this */ 76335500Sbostic if (ps.want_blank) /* put a blank before '{' if '{' is not at 76435500Sbostic * start of line */ 76535500Sbostic *e_code++ = ' '; 76635500Sbostic ps.want_blank = false; 76735500Sbostic *e_code++ = '{'; 76835500Sbostic ps.just_saw_decl = 0; 76935500Sbostic break; 7708800Smckusick 77135500Sbostic case rbrace: /* got a '}' */ 77235500Sbostic if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be 77335500Sbostic * omitted in 77435500Sbostic * declarations */ 77535500Sbostic parse(semicolon); 77635500Sbostic if (ps.p_l_follow) {/* check for unclosed if, for, else. */ 77735500Sbostic diag(1, "Unbalanced parens"); 77835500Sbostic ps.p_l_follow = 0; 77935500Sbostic sp_sw = false; 78035500Sbostic } 78135500Sbostic ps.just_saw_decl = 0; 78235500Sbostic ps.block_init_level--; 78335500Sbostic if (s_code != e_code && !ps.block_init) { /* '}' must be first on 78435500Sbostic * line */ 78535500Sbostic if (verbose) 78635500Sbostic diag(0, "Line broken"); 78735500Sbostic dump_line(); 78835500Sbostic } 78935500Sbostic *e_code++ = '}'; 79035500Sbostic ps.want_blank = true; 79135500Sbostic ps.in_stmt = ps.ind_stmt = false; 79235500Sbostic if (ps.dec_nest > 0) { /* we are in multi-level structure 79335500Sbostic * declaration */ 79435500Sbostic dec_ind = di_stack[--ps.dec_nest]; 79535500Sbostic if (ps.dec_nest == 0 && !ps.in_parameter_declaration) 79635500Sbostic ps.just_saw_decl = 2; 79735500Sbostic ps.in_decl = true; 79835500Sbostic } 79935500Sbostic prefix_blankline_requested = 0; 80035500Sbostic parse(rbrace); /* let parser know about this */ 80135500Sbostic ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead 80235500Sbostic && ps.il[ps.tos] >= ps.ind_level; 80335500Sbostic if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0) 80435500Sbostic postfix_blankline_requested = 1; 80535500Sbostic break; 8068800Smckusick 80735500Sbostic case swstmt: /* got keyword "switch" */ 80835500Sbostic sp_sw = true; 80935500Sbostic hd_type = swstmt; /* keep this for when we have seen the 81035500Sbostic * expression */ 81135500Sbostic goto copy_id; /* go move the token into buffer */ 81235500Sbostic 81335500Sbostic case sp_paren: /* token is if, while, for */ 81435500Sbostic sp_sw = true; /* the interesting stuff is done after the 81524453Smckusick * expression is scanned */ 81635500Sbostic hd_type = (*token == 'i' ? ifstmt : 81735500Sbostic (*token == 'w' ? whilestmt : forstmt)); 8188800Smckusick 81935500Sbostic /* 82035500Sbostic * remember the type of header for later use by parser 82135500Sbostic */ 82235500Sbostic goto copy_id; /* copy the token into line */ 82324453Smckusick 82435500Sbostic case sp_nparen: /* got else, do */ 82535500Sbostic ps.in_stmt = false; 82635500Sbostic if (*token == 'e') { 82735500Sbostic if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) { 82835500Sbostic if (verbose) 82935500Sbostic diag(0, "Line broken"); 83035500Sbostic dump_line();/* make sure this starts a line */ 83135500Sbostic ps.want_blank = false; 8328800Smckusick } 83335500Sbostic force_nl = true;/* also, following stuff must go onto new line */ 83435500Sbostic last_else = 1; 83535500Sbostic parse(elselit); 83635500Sbostic } 83735500Sbostic else { 83835500Sbostic if (e_code != s_code) { /* make sure this starts a line */ 83935500Sbostic if (verbose) 84035500Sbostic diag(0, "Line broken"); 84135500Sbostic dump_line(); 84235500Sbostic ps.want_blank = false; 84335500Sbostic } 84435500Sbostic force_nl = true;/* also, following stuff must go onto new line */ 84535500Sbostic last_else = 0; 84635500Sbostic parse(dolit); 84735500Sbostic } 84835500Sbostic goto copy_id; /* move the token into line */ 8498800Smckusick 85035500Sbostic case decl: /* we have a declaration type (int, register, 85135500Sbostic * etc.) */ 85235500Sbostic parse(decl); /* let parser worry about indentation */ 85335500Sbostic if (ps.last_token == rparen && ps.tos <= 1) { 85435500Sbostic ps.in_parameter_declaration = 1; 85535500Sbostic if (s_code != e_code) { 85635500Sbostic dump_line(); 85735500Sbostic ps.want_blank = 0; 85824453Smckusick } 85935500Sbostic } 86035500Sbostic if (ps.in_parameter_declaration && ps.indent_parameters && ps.dec_nest == 0) { 86135500Sbostic ps.ind_level = ps.i_l_follow = 1; 86235500Sbostic ps.ind_stmt = 0; 86335500Sbostic } 86435500Sbostic ps.in_or_st = true; /* this might be a structure or initialization 86535500Sbostic * declaration */ 86635500Sbostic ps.in_decl = ps.decl_on_line = true; 86735500Sbostic if ( /* !ps.in_or_st && */ ps.dec_nest <= 0) 86835500Sbostic ps.just_saw_decl = 2; 86935500Sbostic prefix_blankline_requested = 0; 87035500Sbostic for (i = 0; token[i++];); /* get length of token */ 8718800Smckusick 87235500Sbostic /* 87335500Sbostic * dec_ind = e_code - s_code + (ps.decl_indent>i ? ps.decl_indent 87435500Sbostic * : i); 87535500Sbostic */ 87635500Sbostic dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i; 87735500Sbostic goto copy_id; 8788800Smckusick 87935500Sbostic case ident: /* got an identifier or constant */ 88035500Sbostic if (ps.in_decl) { /* if we are in a declaration, we must indent 88135500Sbostic * identifier */ 88224453Smckusick if (ps.want_blank) 8838800Smckusick *e_code++ = ' '; 88435500Sbostic ps.want_blank = false; 88535500Sbostic if (is_procname == 0 || !procnames_start_line) { 88635500Sbostic if (!ps.block_init) 88735500Sbostic if (troff && !ps.dumped_decl_indent) { 88835500Sbostic sprintf(e_code, "\n.De %dp+\200p\n", dec_ind * 7); 88935500Sbostic ps.dumped_decl_indent = 1; 89035500Sbostic e_code += strlen(e_code); 89135500Sbostic } 89235500Sbostic else 89335500Sbostic while ((e_code - s_code) < dec_ind) { 894*40275Sbostic CHECK_SIZE_CODE; 89535500Sbostic *e_code++ = ' '; 89635500Sbostic } 89724453Smckusick } 89835500Sbostic else { 89935500Sbostic if (dec_ind && s_code != e_code) 90035500Sbostic dump_line(); 90135500Sbostic dec_ind = 0; 90235500Sbostic ps.want_blank = false; 90335500Sbostic } 90435500Sbostic } 90535500Sbostic else if (sp_sw && ps.p_l_follow == 0) { 90635500Sbostic sp_sw = false; 90735500Sbostic force_nl = true; 90835500Sbostic ps.last_u_d = true; 90935500Sbostic ps.in_stmt = false; 91035500Sbostic parse(hd_type); 91135500Sbostic } 91235500Sbostic copy_id: 91335500Sbostic if (ps.want_blank) 91435500Sbostic *e_code++ = ' '; 91535500Sbostic if (troff && ps.its_a_keyword) { 91635500Sbostic e_code = chfont(&bodyf, &keywordf, e_code); 91735500Sbostic for (t_ptr = token; *t_ptr; ++t_ptr) { 918*40275Sbostic CHECK_SIZE_CODE; 91935500Sbostic *e_code++ = keywordf.allcaps && islower(*t_ptr) 92035500Sbostic ? toupper(*t_ptr) : *t_ptr; 92135500Sbostic } 92235500Sbostic e_code = chfont(&keywordf, &bodyf, e_code); 92335500Sbostic } 92435500Sbostic else 92535500Sbostic for (t_ptr = token; *t_ptr; ++t_ptr) { 926*40275Sbostic CHECK_SIZE_CODE; 9278800Smckusick *e_code++ = *t_ptr; 92824453Smckusick } 92935500Sbostic ps.want_blank = true; 93035500Sbostic break; 9318800Smckusick 93235500Sbostic case period: /* treat a period kind of like a binary 93324453Smckusick * operation */ 93435500Sbostic *e_code++ = '.'; /* move the period into line */ 93535500Sbostic ps.want_blank = false; /* dont put a blank after a period */ 93635500Sbostic break; 9378800Smckusick 93835500Sbostic case comma: 93935500Sbostic ps.want_blank = (s_code != e_code); /* only put blank after comma 94035500Sbostic * if comma does not start the 94135500Sbostic * line */ 94235500Sbostic if (ps.in_decl && is_procname == 0 && !ps.block_init) 94335500Sbostic while ((e_code - s_code) < (dec_ind - 1)) { 944*40275Sbostic CHECK_SIZE_CODE; 94535500Sbostic *e_code++ = ' '; 94635500Sbostic } 9478800Smckusick 94835500Sbostic *e_code++ = ','; 94935500Sbostic if (ps.p_l_follow == 0) { 95035500Sbostic if (ps.block_init_level <= 0) 95124453Smckusick ps.block_init = 0; 95238011Sbostic if (break_comma && (!ps.leave_comma || compute_code_target() + (e_code - s_code) > max_col - 8)) 95335500Sbostic force_nl = true; 95435500Sbostic } 95535500Sbostic break; 9568800Smckusick 95735500Sbostic case preesc: /* got the character '#' */ 95835500Sbostic if ((s_com != e_com) || 95924453Smckusick (s_lab != e_lab) || 96024453Smckusick (s_code != e_code)) 96135500Sbostic dump_line(); 96235500Sbostic *e_lab++ = '#'; /* move whole line to 'label' buffer */ 96335500Sbostic { 96435500Sbostic int in_comment = 0; 96535500Sbostic int com_start = 0; 96635500Sbostic char quote = 0; 96735500Sbostic int com_end = 0; 9688800Smckusick 96938011Sbostic while (*buf_ptr == ' ' || *buf_ptr == '\t') { 97038011Sbostic buf_ptr++; 97138011Sbostic if (buf_ptr >= buf_end) 97238011Sbostic fill_buffer(); 97338011Sbostic } 97435500Sbostic while (*buf_ptr != '\n' || in_comment) { 975*40275Sbostic CHECK_SIZE_LAB; 97635500Sbostic *e_lab = *buf_ptr++; 97735500Sbostic if (buf_ptr >= buf_end) 97835500Sbostic fill_buffer(); 97935500Sbostic switch (*e_lab++) { 98035500Sbostic case BACKSLASH: 98135500Sbostic if (troff) 98235500Sbostic *e_lab++ = BACKSLASH; 98335500Sbostic if (!in_comment) { 98435500Sbostic *e_lab++ = *buf_ptr++; 98535500Sbostic if (buf_ptr >= buf_end) 98635500Sbostic fill_buffer(); 98724453Smckusick } 98835500Sbostic break; 98935500Sbostic case '/': 99035500Sbostic if (*buf_ptr == '*' && !in_comment && !quote) { 99135500Sbostic in_comment = 1; 99235500Sbostic *e_lab++ = *buf_ptr++; 99335500Sbostic com_start = e_lab - s_lab - 2; 99435500Sbostic } 99535500Sbostic break; 99635500Sbostic case '"': 99735500Sbostic if (quote == '"') 99835500Sbostic quote = 0; 99935500Sbostic break; 100035500Sbostic case '\'': 100135500Sbostic if (quote == '\'') 100235500Sbostic quote = 0; 100335500Sbostic break; 100435500Sbostic case '*': 100535500Sbostic if (*buf_ptr == '/' && in_comment) { 100635500Sbostic in_comment = 0; 100735500Sbostic *e_lab++ = *buf_ptr++; 100835500Sbostic com_end = e_lab - s_lab; 100935500Sbostic } 101035500Sbostic break; 10118800Smckusick } 101235500Sbostic } 101335500Sbostic 101435500Sbostic while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 101535500Sbostic e_lab--; 101635500Sbostic if (e_lab - s_lab == com_end && bp_save == 0) { /* comment on 101724453Smckusick * preprocessor line */ 101835500Sbostic if (sc_end == 0) /* if this is the first comment, we 101935500Sbostic * must set up the buffer */ 102035500Sbostic sc_end = &(save_com[0]); 102135500Sbostic else { 102235500Sbostic *sc_end++ = '\n'; /* add newline between 102324453Smckusick * comments */ 102435500Sbostic *sc_end++ = ' '; 102535500Sbostic --line_no; 102624453Smckusick } 102735500Sbostic bcopy(s_lab + com_start, sc_end, com_end - com_start); 102835500Sbostic sc_end += com_end - com_start; 102935500Sbostic if (sc_end >= &save_com[sc_size]) 103035500Sbostic abort(); 103135500Sbostic e_lab = s_lab + com_start; 103235500Sbostic while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 103335500Sbostic e_lab--; 103435500Sbostic bp_save = buf_ptr; /* save current input buffer */ 103535500Sbostic be_save = buf_end; 103635500Sbostic buf_ptr = save_com; /* fix so that subsequent calls to 103735500Sbostic * lexi will take tokens out of 103835500Sbostic * save_com */ 103935500Sbostic *sc_end++ = ' '; /* add trailing blank, just in case */ 104035500Sbostic buf_end = sc_end; 104135500Sbostic sc_end = 0; 10428800Smckusick } 104335500Sbostic *e_lab = '\0'; /* null terminate line */ 104435500Sbostic ps.pcase = false; 104535500Sbostic } 104635500Sbostic 104735500Sbostic if (strncmp(s_lab, "#if", 3) == 0) { 104835500Sbostic if (blanklines_around_conditional_compilation) { 104935500Sbostic register c; 105035500Sbostic prefix_blankline_requested++; 105135500Sbostic while ((c = getc(input)) == '\n'); 105235500Sbostic ungetc(c, input); 105335500Sbostic } 105435500Sbostic if (ifdef_level < sizeof state_stack / sizeof state_stack[0]) { 105535500Sbostic match_state[ifdef_level].tos = -1; 105635500Sbostic state_stack[ifdef_level++] = ps; 105735500Sbostic } 105835500Sbostic else 105935500Sbostic diag(1, "#if stack overflow"); 106035500Sbostic } 106135500Sbostic else if (strncmp(s_lab, "#else", 5) == 0) 106235500Sbostic if (ifdef_level <= 0) 106335500Sbostic diag(1, "Unmatched #else"); 106435500Sbostic else { 106535500Sbostic match_state[ifdef_level - 1] = ps; 106635500Sbostic ps = state_stack[ifdef_level - 1]; 106735500Sbostic } 106835500Sbostic else if (strncmp(s_lab, "#endif", 6) == 0) { 106935500Sbostic if (ifdef_level <= 0) 107035500Sbostic diag(1, "Unmatched #endif"); 107135500Sbostic else { 107235500Sbostic ifdef_level--; 107335500Sbostic 107424453Smckusick #ifdef undef 107535500Sbostic /* 107635500Sbostic * This match needs to be more intelligent before the 107735500Sbostic * message is useful 107835500Sbostic */ 107935500Sbostic if (match_state[ifdef_level].tos >= 0 108035500Sbostic && bcmp(&ps, &match_state[ifdef_level], sizeof ps)) 108135500Sbostic diag(0, "Syntactically inconsistant #ifdef alternatives."); 108224453Smckusick #endif 108335500Sbostic } 108435500Sbostic if (blanklines_around_conditional_compilation) { 108535500Sbostic postfix_blankline_requested++; 108635500Sbostic n_real_blanklines = 0; 108735500Sbostic } 108835500Sbostic } 108935500Sbostic break; /* subsequent processing of the newline 109035500Sbostic * character will cause the line to be printed */ 10918800Smckusick 109235500Sbostic case comment: /* we have gotten a /* this is a biggie */ 109335500Sbostic if (flushed_nl) { /* we should force a broken line here */ 109435500Sbostic flushed_nl = false; 109535500Sbostic dump_line(); 109635500Sbostic ps.want_blank = false; /* dont insert blank at line start */ 109735500Sbostic force_nl = false; 109835500Sbostic } 109935500Sbostic pr_comment(); 110035500Sbostic break; 110124453Smckusick } /* end of big switch stmt */ 110235500Sbostic 110335500Sbostic *e_code = '\0'; /* make sure code section is null terminated */ 110424453Smckusick if (type_code != comment && type_code != newline && type_code != preesc) 110524453Smckusick ps.last_token = type_code; 110624453Smckusick } /* end of main while (1) loop */ 110736970Sbostic } 11088800Smckusick 11098800Smckusick /* 111035500Sbostic * copy input file to backup file if in_name is /blah/blah/blah/file, then 111135500Sbostic * backup file will be ".Bfile" then make the backup file the input and 111235500Sbostic * original input file the output 11138800Smckusick */ 111424453Smckusick bakcopy() 111524453Smckusick { 111624453Smckusick int n, 111724453Smckusick bakchn; 111835500Sbostic char buff[8 * 1024]; 111924453Smckusick register char *p; 11208800Smckusick 112135500Sbostic /* construct file name .Bfile */ 112235500Sbostic for (p = in_name; *p; p++); /* skip to end of string */ 112335500Sbostic while (p > in_name && *p != '/') /* find last '/' */ 112435500Sbostic p--; 112535500Sbostic if (*p == '/') 11268800Smckusick p++; 112724453Smckusick sprintf(bakfile, "%s.BAK", p); 11288800Smckusick 112924453Smckusick /* copy in_name to backup file */ 113024453Smckusick bakchn = creat(bakfile, 0600); 113136970Sbostic if (bakchn < 0) 113236970Sbostic err(bakfile); 113335500Sbostic while (n = read(fileno(input), buff, sizeof buff)) 113436970Sbostic if (write(bakchn, buff, n) != n) 113536970Sbostic err(bakfile); 113636970Sbostic if (n < 0) 113736970Sbostic err(in_name); 113824453Smckusick close(bakchn); 113924453Smckusick fclose(input); 11408800Smckusick 114124453Smckusick /* re-open backup file as the input file */ 114224453Smckusick input = fopen(bakfile, "r"); 114336970Sbostic if (input == 0) 114436970Sbostic err(bakfile); 114524453Smckusick /* now the original input file will be the output */ 114624453Smckusick output = fopen(in_name, "w"); 114735500Sbostic if (output == 0) { 114824453Smckusick unlink(bakfile); 114936970Sbostic err(in_name); 11508800Smckusick } 11518800Smckusick } 115236970Sbostic 115336970Sbostic err(msg) 115436970Sbostic char *msg; 115536970Sbostic { 115636970Sbostic extern int errno; 115736970Sbostic char *strerror(); 115836970Sbostic 115936970Sbostic (void)fprintf(stderr, "indent: %s: %s\n", msg, strerror(errno)); 116036970Sbostic exit(1); 116136970Sbostic } 1162