121968Sdist /* 221968Sdist * Copyright (c) 1980 Regents of the University of California. 333767Sbostic * Copyright (c) 1976 Board of Trustees of the University of Illinois. 433767Sbostic * All rights reserved. 533767Sbostic * 633767Sbostic * Redistribution and use in source and binary forms are permitted 7*34885Sbostic * provided that the above copyright notice and this paragraph are 8*34885Sbostic * duplicated in all such forms and that any documentation, 9*34885Sbostic * advertising materials, and other materials related to such 10*34885Sbostic * distribution and use acknowledge that the software was developed 11*34885Sbostic * by the University of California, Berkeley and the University 12*34885Sbostic * of Illinois, Urbana. The name of either 13*34885Sbostic * University may not be used to endorse or promote products derived 14*34885Sbostic * from this software without specific prior written permission. 15*34885Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 16*34885Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 17*34885Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1821968Sdist */ 198800Smckusick 2021968Sdist #ifndef lint 2121968Sdist char copyright[] = 2221968Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 2333767Sbostic Copyright (c) 1976 Board of Trustees of the University of Illinois.\n\ 2421968Sdist All rights reserved.\n"; 2533767Sbostic #endif /* not lint */ 2621968Sdist 2721968Sdist #ifndef lint 28*34885Sbostic static char sccsid[] = "@(#)indent.c 5.8 (Berkeley) 06/29/88"; 2933767Sbostic #endif /* not lint */ 3021968Sdist 3133767Sbostic /* 328800Smckusick NAME: 3324453Smckusick indent main program 3424453Smckusick 358800Smckusick FUNCTION: 3624453Smckusick This is the main program of the indent program. Indent will take a C 3724453Smckusick program source and reformat it into a semi-reasonable form. 3824453Smckusick 398800Smckusick ALGORITHM: 4024453Smckusick The routine lexi scans tokens and passes them back one at a time to the 4124453Smckusick main routine. The subroutine parse takes care of much of the work of 4224453Smckusick figuring indentation level. 4324453Smckusick 4424453Smckusick 1) Call lexi 4524453Smckusick 2) Enter a monster switch statement on the code returned by lexi. If 4624453Smckusick the indentation level for the line yet to be printed should be 4724453Smckusick changed, set the variable ps.ind_level. If the indentation level for 4824453Smckusick the following line should be changed, set the variable ps.i_l_follow. 498800Smckusick 5024453Smckusick */ 5133228Sbostic #include "indent_globs.h" 5233228Sbostic #include "indent_codes.h" 538800Smckusick 5424453Smckusick char *in_name = "Standard Input"; /* will always point to name of 5524453Smckusick * input file */ 5624453Smckusick char *out_name = "Standard Output"; /* will always point to 5724453Smckusick * name of output file */ 5824453Smckusick char bakfile[32] = ""; 598800Smckusick 6024453Smckusick main(argc, argv) 6124453Smckusick int argc; 6224453Smckusick char **argv; 638800Smckusick { 6430984Sbostic extern int found_err; /* if any error occurred */ 658800Smckusick 6624453Smckusick int dec_ind; /* current indentation for declarations */ 6724453Smckusick int di_stack[20]; /* a stack of structure indentation levels */ 6824453Smckusick int flushed_nl; /* used when buffering up comments to 6924453Smckusick * remember that a newline was passed over */ 7024453Smckusick int force_nl; /* when true, code must be broken */ 7124453Smckusick int hd_type; /* used to store type of stmt for if 7224453Smckusick * (...), for (...), etc */ 7324453Smckusick register int i; /* local loop counter */ 7424453Smckusick register int j; /* local loop counter */ 7524453Smckusick int scase; /* set to true when we see a case, so we 7624453Smckusick * will know what to do with the following 7724453Smckusick * colon */ 7824453Smckusick int sp_sw; /* when true, we are in the expressin of 7924453Smckusick * if(...), while(...), etc. */ 8024453Smckusick int squest; /* when this is positive, we have seen a ? 8124453Smckusick * without the matching : in a <c>?<s>:<s> 8224453Smckusick * construct */ 8324453Smckusick register char *t_ptr; /* used for copying tokens */ 8424453Smckusick int type_code; /* the type of token, returned by lexi */ 858800Smckusick 8624453Smckusick int last_else = 0; /* true iff last keyword was an else */ 878800Smckusick 888800Smckusick 8924453Smckusick /*-----------------------------------------------*\ 9024648Smckusick | INITIALIZATION | 9124648Smckusick \*-----------------------------------------------*/ 928800Smckusick 938800Smckusick 9424453Smckusick ps.p_stack[0] = stmt; /* this is the parser's stack */ 9524453Smckusick ps.last_nl = true; /* this is true if the last thing scanned 9624453Smckusick * was a newline */ 9724453Smckusick ps.last_token = semicolon; 9824453Smckusick combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and 9924453Smckusick * comment buffers */ 1008800Smckusick combuf[1] = codebuf[1] = labbuf[1] = '\0'; 1018800Smckusick s_lab = e_lab = labbuf + 1; 1028800Smckusick s_code = e_code = codebuf + 1; 1038800Smckusick s_com = e_com = combuf + 1; 1048800Smckusick 1058800Smckusick buf_ptr = buf_end = in_buffer; 1068800Smckusick line_no = 1; 10724453Smckusick had_eof = ps.in_decl = ps.decl_on_line = break_comma = false; 1088800Smckusick sp_sw = force_nl = false; 10924453Smckusick ps.in_or_st = false; 11024453Smckusick ps.bl_line = true; 1118800Smckusick dec_ind = 0; 11224453Smckusick di_stack[ps.dec_nest = 0] = 0; 11324453Smckusick ps.want_blank = ps.in_stmt = ps.ind_stmt = false; 1148800Smckusick 1158800Smckusick 11624453Smckusick scase = ps.pcase = false; 1178800Smckusick squest = 0; 1188800Smckusick sc_end = 0; 1198800Smckusick bp_save = 0; 1208800Smckusick be_save = 0; 1218800Smckusick 12224453Smckusick output = 0; 1238800Smckusick 1248800Smckusick 1258800Smckusick 12624453Smckusick /*--------------------------------------------------*\ 12724648Smckusick | COMMAND LINE SCAN 12824648Smckusick \*--------------------------------------------------*/ 1298800Smckusick 13024648Smckusick set_defaults(); 1318800Smckusick 13224648Smckusick /* 13324648Smckusick * Unfortunately, we must look for -npro here because the profiles 13424648Smckusick * are read before the command line arguments. 13524648Smckusick */ 13624453Smckusick for (i = 1; i < argc; ++i) 13724453Smckusick if (strcmp(argv[i], "-npro") == 0) 13824453Smckusick break; 13924453Smckusick if (i >= argc) 14024453Smckusick set_profile(); 1418800Smckusick 14224648Smckusick input = 0; /* cancel -st if it was in the profiles, */ 14324648Smckusick output = 0; /* as it doesn't make any sense there. */ 14424648Smckusick 1458800Smckusick for (i = 1; i < argc; ++i) { 14624453Smckusick 14724453Smckusick /* 14824453Smckusick * look thru args (if any) for changes to defaults 14924453Smckusick */ 1508800Smckusick if (argv[i][0] != '-') {/* no flag on parameter */ 15124453Smckusick if (input == 0) { /* we must have the input file */ 15224453Smckusick in_name = argv[i]; /* remember name of input file */ 15324453Smckusick input = fopen(in_name, "r"); 15424453Smckusick if (input == 0) { /* check for open error */ 15524648Smckusick fprintf(stderr, "indent: can't open %s\n", argv[i]); 15624648Smckusick exit(1); 1578800Smckusick } 1588800Smckusick continue; 15924453Smckusick } else if (output == 0) { /* we have the output file */ 16024453Smckusick out_name = argv[i]; /* remember name of output file */ 16124453Smckusick if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite 16224453Smckusick * the file */ 16324648Smckusick fprintf(stderr, "indent: input and output files must be different\n"); 16424648Smckusick exit(1); 16524453Smckusick } 16624453Smckusick output = fopen(out_name, "w"); 16724453Smckusick if (output == 0) { /* check for create error */ 16824648Smckusick fprintf(stderr, "indent: can't create %s\n", argv[i]); 16924648Smckusick exit(1); 17024453Smckusick } 17124453Smckusick continue; 1728800Smckusick } 17324648Smckusick fprintf(stderr, "indent: unknown parameter: %s\n", argv[i]); 17424648Smckusick exit(1); 17524453Smckusick } else 17624453Smckusick set_option(argv[i]); 1778800Smckusick 17824453Smckusick } /* end of for */ 17924453Smckusick if (input == 0) { 18024453Smckusick printf("Usage: indent file [ outfile ] [ options ]\n"); 18124648Smckusick exit(1); 18224453Smckusick } 18324453Smckusick if (output == 0) 18424453Smckusick if (troff) 18524453Smckusick output = stdout; 18624453Smckusick else { 18724453Smckusick out_name = in_name; 18824453Smckusick bakcopy(); 1898800Smckusick } 19024648Smckusick 19124648Smckusick /* 19224648Smckusick * Adjust parameters that are out of range, or set defaults if 19324648Smckusick * no values were specified. 19424648Smckusick */ 19524453Smckusick if (ps.com_ind <= 1) 19624453Smckusick ps.com_ind = 2; /* dont put normal comments before column 19724453Smckusick * 2 */ 19824453Smckusick if (block_comment_max_col <= 0) 19924453Smckusick block_comment_max_col = max_col; 20024453Smckusick if (ps.decl_com_ind <= 0) /* if not specified by user, set this */ 20124648Smckusick ps.decl_com_ind = ps.ljust_decl ? ps.com_ind - 8 : ps.com_ind; 20224648Smckusick if (ps.decl_com_ind <= 1) 20324648Smckusick ps.decl_com_ind = 2; 20424453Smckusick if (continuation_indent == 0) 20524453Smckusick continuation_indent = ps.ind_size; 20624453Smckusick fill_buffer(); /* get first batch of stuff into input 20724453Smckusick * buffer */ 2088800Smckusick 20924453Smckusick parse(semicolon); 21024453Smckusick { 21124453Smckusick register char *p = buf_ptr; 21224453Smckusick register col = 1; 2138800Smckusick 21424453Smckusick while (1) { 21524453Smckusick if (*p == ' ') 21624453Smckusick col++; 21724453Smckusick else if (*p == '\t') 21824453Smckusick col = ((col - 1) & ~7) + 9; 21924453Smckusick else 22024453Smckusick break; 22124453Smckusick p++; 22224453Smckusick }; 22324453Smckusick if (col > ps.ind_size) 22424453Smckusick ps.ind_level = ps.i_l_follow = col / ps.ind_size; 2258800Smckusick } 22624453Smckusick if (troff) { 22724453Smckusick register char *p = in_name, 22824453Smckusick *beg = in_name; 22924453Smckusick 23024453Smckusick while (*p) 23124453Smckusick if (*p++ == '/') 23224453Smckusick beg = p; 23324453Smckusick fprintf(output, ".Fn \"%s\"\n", beg); 2348800Smckusick } 2358800Smckusick 23624453Smckusick /* 23724453Smckusick * START OF MAIN LOOP 23824453Smckusick */ 2398800Smckusick 24024453Smckusick while (1) { /* this is the main loop. it will go 24124453Smckusick * until we reach eof */ 24224453Smckusick int is_procname; 2438800Smckusick 24424453Smckusick type_code = lexi(); /* lexi reads one token. The actual 24524453Smckusick * characters read are stored in "token". 24624453Smckusick * lexi returns a code indicating the type 24724453Smckusick * of token */ 24824453Smckusick is_procname = ps.procname[0]; 2498800Smckusick 25024453Smckusick /* 25124453Smckusick * The following code moves everything following an if (), while 25224453Smckusick * (), else, etc. up to the start of the following stmt to a 25324453Smckusick * buffer. This allows proper handling of both kinds of brace 25424453Smckusick * placement. 25524453Smckusick */ 2568800Smckusick 2578800Smckusick flushed_nl = false; 25824453Smckusick while (ps.search_brace) { /* if we scanned an if(), while(), 25924453Smckusick * etc., we might need to copy 26024453Smckusick * stuff into a buffer we must 26124453Smckusick * loop, copying stuff into 26224453Smckusick * save_com, until we find the 26324453Smckusick * start of the stmt which follows 26424453Smckusick * the if, or whatever */ 2658800Smckusick switch (type_code) { 26624453Smckusick case newline: 2678800Smckusick ++line_no; 2688800Smckusick flushed_nl = true; 26924453Smckusick case form_feed: 27024453Smckusick break; /* form feeds and newlines found here will 27124453Smckusick * be ignored */ 2728800Smckusick 27324453Smckusick case lbrace: /* this is a brace that starts the 27424453Smckusick * compound stmt */ 27524453Smckusick if (sc_end == 0) { /* ignore buffering if a comment 27624453Smckusick * wasnt stored up */ 27724453Smckusick ps.search_brace = false; 2788800Smckusick goto check_type; 2798800Smckusick } 2808800Smckusick if (btype_2) { 28124453Smckusick save_com[0] = '{'; /* we either want to put 28224453Smckusick * the brace right after 28324453Smckusick * the if */ 28424453Smckusick goto sw_buffer; /* go to common code to get out of 28524453Smckusick * this loop */ 2868800Smckusick } 28724453Smckusick case comment: /* we have a comment, so we must copy it 28824453Smckusick * into the buffer */ 28924453Smckusick if (!flushed_nl) { 29024453Smckusick if (sc_end == 0) { /* if this is the first 29124453Smckusick * comment, we must set up 29224453Smckusick * the buffer */ 29324453Smckusick save_com[0] = save_com[1] = ' '; 29424453Smckusick sc_end = &(save_com[2]); 29524453Smckusick } else { 29624453Smckusick *sc_end++ = '\n'; /* add newline between 29724453Smckusick * comments */ 29824453Smckusick *sc_end++ = ' '; 29924453Smckusick --line_no; 30024453Smckusick } 30124453Smckusick *sc_end++ = '/'; /* copy in start of 30224453Smckusick * comment */ 30324453Smckusick *sc_end++ = '*'; 3048800Smckusick 30524453Smckusick for (;;) { /* loop until we get to the end of 30624453Smckusick * the comment */ 30724453Smckusick *sc_end = *buf_ptr++; 30824453Smckusick if (buf_ptr >= buf_end) 30924453Smckusick fill_buffer(); 31024453Smckusick 31124453Smckusick if (*sc_end++ == '*' && *buf_ptr == '/') 31224453Smckusick break; /* we are at end of comment */ 31324453Smckusick 31424453Smckusick if (sc_end >= &(save_com[sc_size])) { /* check for temp buffer 31524453Smckusick * overflow */ 31624453Smckusick diag(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever."); 31724453Smckusick fflush(output); 31824648Smckusick exit(1); 31924453Smckusick } 32024453Smckusick } 32124453Smckusick *sc_end++ = '/'; /* add ending slash */ 32224453Smckusick if (++buf_ptr >= buf_end) /* get past / in buffer */ 32324453Smckusick fill_buffer(); 32424453Smckusick break; 32524453Smckusick } 32624453Smckusick default: /* it is the start of a normal statment */ 32724453Smckusick if (flushed_nl) /* if we flushed a newline, make 32824453Smckusick * sure it is put back */ 3298800Smckusick force_nl = true; 33024453Smckusick if (type_code == sp_paren && *token == 'i' 33124453Smckusick && last_else && ps.else_if 33224453Smckusick || type_code == sp_nparen && *token == 'e' 33324453Smckusick && e_code != s_code && e_code[-1] == '}') 33424453Smckusick force_nl = false; 3358800Smckusick 33624453Smckusick if (sc_end == 0) { /* ignore buffering if comment 33724453Smckusick * wasnt saved up */ 33824453Smckusick ps.search_brace = false; 3398800Smckusick goto check_type; 3408800Smckusick } 34124453Smckusick if (force_nl) { /* if we should insert a nl here, 34224453Smckusick * put it into the buffer */ 3438800Smckusick force_nl = false; 34424453Smckusick --line_no; /* this will be re-increased when 34524453Smckusick * the nl is read from the buffer */ 3468800Smckusick *sc_end++ = '\n'; 3478800Smckusick *sc_end++ = ' '; 34824453Smckusick if (verbose && !flushed_nl) /* print error msg if 34924453Smckusick * the line was not 35024453Smckusick * already broken */ 35124453Smckusick diag(0, "Line broken"); 3528800Smckusick flushed_nl = false; 3538800Smckusick } 3548800Smckusick for (t_ptr = token; *t_ptr; ++t_ptr) 35524453Smckusick *sc_end++ = *t_ptr; /* copy token into temp 35624453Smckusick * buffer */ 3578800Smckusick 35824453Smckusick sw_buffer: 35924453Smckusick ps.search_brace = false; /* stop looking for start 36024453Smckusick * of stmt */ 36124453Smckusick bp_save = buf_ptr; /* save current input buffer */ 3628800Smckusick be_save = buf_end; 36324453Smckusick buf_ptr = save_com; /* fix so that subsequent calls to 36424453Smckusick * lexi will take tokens out of 36524453Smckusick * save_com */ 36624453Smckusick *sc_end++ = ' '; /* add trailing blank, just in 36724453Smckusick * case */ 3688800Smckusick buf_end = sc_end; 3698800Smckusick sc_end = 0; 3708800Smckusick break; 37124453Smckusick } /* end of switch */ 37224453Smckusick if (type_code != 0) /* we must make this check, just in case 37324453Smckusick * there was an unexpected EOF */ 37424453Smckusick type_code = lexi(); /* read another token */ 37524453Smckusick is_procname = ps.procname[0]; 37624453Smckusick } /* end of while (serach_brace) */ 37724453Smckusick last_else = 0; 37824453Smckusick check_type: 37924453Smckusick if (type_code == 0) { /* we got eof */ 3808800Smckusick if (s_lab != e_lab || s_code != e_code 38124453Smckusick || s_com != e_com) /* must dump end of line */ 38224453Smckusick dump_line(); 38324453Smckusick if (ps.tos > 1) /* check for balanced braces */ 38424453Smckusick diag(1, "Stuff missing from end of file."); 3858800Smckusick 3868800Smckusick if (verbose) { 38724453Smckusick printf("There were %d output lines and %d comments\n", 38824453Smckusick ps.out_lines, ps.out_coms); 38924453Smckusick printf("(Lines with comments)/(Lines with code): %6.3f\n", 39024453Smckusick (1.0 * ps.com_lines) / code_lines); 3918800Smckusick } 39224453Smckusick fflush(output); 39330984Sbostic exit(ps.tos > 1 || found_err); 3948800Smckusick } 3958800Smckusick if ( 39624453Smckusick (type_code != comment) && 39724453Smckusick (type_code != newline) && 39824453Smckusick (type_code != preesc) && 39924453Smckusick (type_code != form_feed)) { 4008800Smckusick if ( 40124453Smckusick force_nl 40224453Smckusick && 40324453Smckusick (type_code != semicolon) && 40424453Smckusick ( 40524453Smckusick type_code != lbrace 40624453Smckusick || 40724453Smckusick !btype_2 40824453Smckusick )) { /* we should force a broken line here */ 4098800Smckusick if (verbose && !flushed_nl) 41024453Smckusick diag(0, "Line broken"); 4118800Smckusick flushed_nl = false; 41224453Smckusick dump_line(); 41324453Smckusick ps.want_blank = false; /* dont insert blank at line start */ 4148800Smckusick force_nl = false; 4158800Smckusick } 41624453Smckusick ps.in_stmt = true; /* turn on flag which causes an extra 41724453Smckusick * level of indentation. this is turned 41824453Smckusick * off by a ; or '}' */ 41924453Smckusick if (s_com != e_com) { /* the turkey has embedded a 42024453Smckusick * comment in a line. fix it */ 4218800Smckusick *e_code++ = ' '; 4228800Smckusick for (t_ptr = s_com; *t_ptr; ++t_ptr) 4238800Smckusick *e_code++ = *t_ptr; 4248800Smckusick *e_code++ = ' '; 42524453Smckusick *e_code = '\0'; /* null terminate code sect */ 42624453Smckusick ps.want_blank = false; 4278800Smckusick e_com = s_com; 4288800Smckusick } 42924453Smckusick } else if (type_code != comment) /* preserve force_nl thru 43024453Smckusick * a comment */ 43124453Smckusick force_nl = false; 4328800Smckusick 43324453Smckusick /* 43424453Smckusick * cancel forced newline after newline, form feed, etc 43524453Smckusick */ 4368800Smckusick 4378800Smckusick 4388800Smckusick 43924453Smckusick /*----------------------------------------------------*\ 44024648Smckusick | do switch on type of token scanned 44124648Smckusick \*----------------------------------------------------*/ 44224453Smckusick switch (type_code) { /* now, decide what to do with the token */ 44324453Smckusick 44424453Smckusick case form_feed: /* found a form feed in line */ 44524453Smckusick ps.use_ff = true; /* a form feed is treated much 44624453Smckusick * like a newline */ 44724453Smckusick dump_line(); 44824453Smckusick ps.want_blank = false; 4498800Smckusick break; 4508800Smckusick 45124453Smckusick case newline: 45224453Smckusick if (ps.last_token != comma || ps.p_l_follow > 0 45324453Smckusick || !ps.leave_comma || !break_comma || s_com != e_com) { 45424453Smckusick dump_line(); 45524453Smckusick ps.want_blank = false; 45624453Smckusick } 45724453Smckusick ++line_no; /* keep track of input line number */ 4588800Smckusick break; 4598800Smckusick 46024453Smckusick case lparen: /* got a '(' or '[' */ 46124453Smckusick ++ps.p_l_follow;/* count parens to make Healy happy */ 46224453Smckusick if (ps.want_blank && *token != '[' && 46324453Smckusick (ps.last_token != ident || proc_calls_space 46424453Smckusick || (ps.its_a_keyword && !ps.sizeof_keyword))) 4658800Smckusick *e_code++ = ' '; 46624453Smckusick if (ps.in_decl && !ps.block_init) 46724453Smckusick if (troff && !ps.dumped_decl_indent) { 46824453Smckusick ps.dumped_decl_indent = 1; 46924453Smckusick sprintf(e_code, "\\c\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); 47024453Smckusick e_code += strlen(e_code); 47124453Smckusick } else { 47224453Smckusick while ((e_code - s_code) < dec_ind) 47324453Smckusick *e_code++ = ' '; 47424453Smckusick *e_code++ = token[0]; 47524453Smckusick } else 47624453Smckusick *e_code++ = token[0]; 47724453Smckusick ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code; 47824453Smckusick ps.want_blank = false; 47924453Smckusick if (ps.in_or_st && *token == '(') { 4808800Smckusick 48124453Smckusick /* 48224453Smckusick * this is a kluge to make sure that declarations will 48324453Smckusick * be aligned right if proc decl has an explicit type 48424453Smckusick * on it, i.e. "int a(x) {..." 48524453Smckusick */ 48624453Smckusick parse(semicolon); /* I said this was a kluge... */ 48724453Smckusick ps.in_or_st = false; /* turn off flag for 48824453Smckusick * structure decl or 48924453Smckusick * initialization */ 4908800Smckusick } 49124453Smckusick if (ps.sizeof_keyword) ps.sizeof_mask |= 1<<ps.p_l_follow; 4928800Smckusick break; 4938800Smckusick 49424453Smckusick case rparen: /* got a ')' or ']' */ 49524453Smckusick if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask) { 49624453Smckusick ps.last_u_d = true; 49724453Smckusick ps.cast_mask &= (1 << ps.p_l_follow) - 1; 4988800Smckusick } 49924453Smckusick ps.sizeof_mask &= (1 << ps.p_l_follow) - 1; 50024453Smckusick if (--ps.p_l_follow < 0) { 50124453Smckusick ps.p_l_follow = 0; 50224453Smckusick diag(0, "Extra %c", *token); 50324453Smckusick } 50424453Smckusick if (e_code == s_code) /* if the paren starts the line */ 50524453Smckusick ps.paren_level = ps.p_l_follow; /* then indent it */ 5068800Smckusick 5078800Smckusick *e_code++ = token[0]; 50824453Smckusick ps.want_blank = true; 5098800Smckusick 51024453Smckusick if (sp_sw && (ps.p_l_follow == 0)) { /* check for end of if 51124453Smckusick * (...), or some such */ 5128800Smckusick sp_sw = false; 51324453Smckusick force_nl = true; /* must force newline after if */ 51424453Smckusick ps.last_u_d = true; /* inform lexi that a following 51524453Smckusick * operator is unary */ 51624453Smckusick ps.in_stmt = false; /* dont use stmt continuation 51724453Smckusick * indentation */ 5188800Smckusick 51924453Smckusick parse(hd_type); /* let parser worry about if, or 52024453Smckusick * whatever */ 5218800Smckusick } 52224453Smckusick ps.search_brace = btype_2; /* this should insure that 52324453Smckusick * constructs such as 52424453Smckusick * main(){...} and 52524453Smckusick * int[]{...} have their 52624453Smckusick * braces put in the right 52724453Smckusick * place */ 5288800Smckusick break; 5298800Smckusick 53024453Smckusick case unary_op: /* this could be any unary operation */ 53124453Smckusick if (ps.want_blank) 5328800Smckusick *e_code++ = ' '; 5338800Smckusick 53424453Smckusick if (troff && !ps.dumped_decl_indent && ps.in_decl) { 53524453Smckusick sprintf(e_code, "\\c\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); 53624453Smckusick ps.dumped_decl_indent = 1; 53724453Smckusick e_code += strlen(e_code); 53824453Smckusick } else { 53924453Smckusick char *res = token; 54024453Smckusick 54124453Smckusick if (ps.in_decl && !ps.block_init) { /* if this is a unary op 54224453Smckusick * in a declaration, we 54324453Smckusick * should indent this 54424453Smckusick * token */ 54524453Smckusick for (i = 0; token[i]; ++i); /* find length of token */ 54624453Smckusick while ((e_code - s_code) < (dec_ind - i)) 54724453Smckusick *e_code++ = ' '; /* pad it */ 54824453Smckusick } 54924453Smckusick if (troff && token[0] == '-' && token[1] == '>') 55024453Smckusick res = "\\(->"; 55124453Smckusick for (t_ptr = res; *t_ptr; ++t_ptr) 55224453Smckusick *e_code++ = *t_ptr; 5538800Smckusick } 55424453Smckusick ps.want_blank = false; 5558800Smckusick break; 5568800Smckusick 55724453Smckusick case binary_op: /* any binary operation */ 55824453Smckusick do_binary: 55924453Smckusick if (ps.want_blank) 5608800Smckusick *e_code++ = ' '; 56124453Smckusick { 56224453Smckusick char *res = token; 56324453Smckusick 56424453Smckusick if (troff) 56524453Smckusick switch (token[0]) { 56624453Smckusick case '<': 56724453Smckusick if (token[1] == '=') 56824453Smckusick res = "\\(<="; 56924453Smckusick break; 57024453Smckusick case '>': 57124453Smckusick if (token[1] == '=') 57224453Smckusick res = "\\(>="; 57324453Smckusick break; 57424453Smckusick case '!': 57524453Smckusick if (token[1] == '=') 57624453Smckusick res = "\\(!="; 57724453Smckusick break; 57824453Smckusick case '|': 57924453Smckusick if (token[1] == '|') 58024453Smckusick res = "\\(br\\(br"; 58124453Smckusick else if (token[1] == 0) 58224453Smckusick res = "\\(br"; 58324453Smckusick break; 58424676Smckusick case '-': 58524676Smckusick if (token[1] == '>') 58624676Smckusick res = "\\(->"; 58724453Smckusick } 58824453Smckusick for (t_ptr = res; *t_ptr; ++t_ptr) 58924453Smckusick *e_code++ = *t_ptr; /* move the operator */ 59024453Smckusick } 59124453Smckusick ps.want_blank = true; 5928800Smckusick break; 5938800Smckusick 59424453Smckusick case postop: /* got a trailing ++ or -- */ 5958800Smckusick *e_code++ = token[0]; 5968800Smckusick *e_code++ = token[1]; 59724453Smckusick ps.want_blank = true; 5988800Smckusick break; 5998800Smckusick 60024453Smckusick case question: /* got a ? */ 60124453Smckusick squest++; /* this will be used when a later colon 60224453Smckusick * appears so we can distinguish the 60324453Smckusick * <c>?<n>:<n> construct */ 60424453Smckusick if (ps.want_blank) 6058800Smckusick *e_code++ = ' '; 6068800Smckusick *e_code++ = '?'; 60724453Smckusick ps.want_blank = true; 6088800Smckusick break; 6098800Smckusick 61024453Smckusick case casestmt: /* got word 'case' or 'default' */ 61124453Smckusick scase = true; /* so we can process the later colon 61224453Smckusick * properly */ 61324453Smckusick goto copy_id; 6148800Smckusick 61524453Smckusick case colon: /* got a ':' */ 61624453Smckusick if (squest > 0) { /* it is part of the <c>?<n>: <n> 61724453Smckusick * construct */ 6188800Smckusick --squest; 61924453Smckusick if (ps.want_blank) 6208800Smckusick *e_code++ = ' '; 6218800Smckusick *e_code++ = ':'; 62224453Smckusick ps.want_blank = true; 6238800Smckusick break; 6248800Smckusick } 62524453Smckusick if (ps.in_decl) { 62624453Smckusick *e_code++ = ':'; 62724453Smckusick ps.want_blank = false; 62824453Smckusick break; 62924453Smckusick } 63024453Smckusick ps.in_stmt = false; /* seeing a label does not imply 63124453Smckusick * we are in a stmt */ 6328800Smckusick for (t_ptr = s_code; *t_ptr; ++t_ptr) 63324453Smckusick *e_lab++ = *t_ptr; /* turn everything so far into a 63424453Smckusick * label */ 6358800Smckusick e_code = s_code; 6368800Smckusick *e_lab++ = ':'; 6378800Smckusick *e_lab++ = ' '; 6388800Smckusick *e_lab = '\0'; 6398800Smckusick 64024453Smckusick force_nl = ps.pcase = scase; /* ps.pcase will be used 64124453Smckusick * by dump_line to decide 64224453Smckusick * how to indent the 64324453Smckusick * label. force_nl will 64424453Smckusick * force a case n: to be 64524453Smckusick * on a line by itself */ 6468800Smckusick scase = false; 64724453Smckusick ps.want_blank = false; 6488800Smckusick break; 6498800Smckusick 65024453Smckusick case semicolon: /* got a ';' */ 65124453Smckusick ps.in_or_st = false; /* we are not in an initialization 65224453Smckusick * or structure declaration */ 65324453Smckusick scase = false; /* these will only need resetting in a 65424453Smckusick * error */ 6558800Smckusick squest = 0; 65624453Smckusick if (ps.last_token == rparen) 65724453Smckusick ps.in_parameter_declaration = 0; 65824453Smckusick ps.cast_mask = 0; 65924453Smckusick ps.sizeof_mask = 0; 66024453Smckusick ps.block_init = 0; 66124453Smckusick ps.just_saw_decl--; 6628800Smckusick 66324453Smckusick if (ps.in_decl && s_code == e_code && !ps.block_init) 6648800Smckusick while ((e_code - s_code) < (dec_ind - 1)) 6658800Smckusick *e_code++ = ' '; 6668800Smckusick 66724453Smckusick ps.in_decl = (ps.dec_nest > 0); /* if we were in a first 66824453Smckusick * level structure 66924453Smckusick * declaration, we arent 67024453Smckusick * any more */ 6718800Smckusick 67224453Smckusick if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) { 67324453Smckusick 67424453Smckusick /* 67524453Smckusick * This should be true iff there were unbalanced 67624453Smckusick * parens in the stmt. It is a bit complicated, 67724453Smckusick * because the semicolon might be in a for stmt 67824453Smckusick */ 67924453Smckusick diag(1, "Unbalanced parens"); 68024453Smckusick ps.p_l_follow = 0; 68124453Smckusick if (sp_sw) {/* this is a check for a if, while, etc. 68224453Smckusick * with unbalanced parens */ 6838800Smckusick sp_sw = false; 68424453Smckusick parse(hd_type); /* dont lose the if, or whatever */ 6858800Smckusick } 6868800Smckusick } 6878800Smckusick *e_code++ = ';'; 68824453Smckusick ps.want_blank = true; 68924453Smckusick ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in 69024453Smckusick * the middle of a stmt */ 6918800Smckusick 69224453Smckusick if (!sp_sw) { /* if not if for (;;) */ 69324453Smckusick parse(semicolon); /* let parser know about end of 69424453Smckusick * stmt */ 69524453Smckusick force_nl = true; /* force newline after a end of 69624453Smckusick * stmt */ 6978800Smckusick } 6988800Smckusick break; 6998800Smckusick 70024453Smckusick case lbrace: /* got a '{' */ 70124453Smckusick ps.in_stmt = false; /* dont indent the {} */ 70224453Smckusick if (!ps.block_init) 70324453Smckusick force_nl = true; /* force other stuff on same line 70424453Smckusick * as '{' onto new line */ 7058800Smckusick 70624453Smckusick if (s_code != e_code && !ps.block_init) { 70724453Smckusick if (!btype_2) { 70824453Smckusick dump_line(); 70924453Smckusick ps.want_blank = false; 71024453Smckusick } else if (ps.in_parameter_declaration && !ps.in_or_st) { 71124453Smckusick ps.i_l_follow = 0; 71224453Smckusick dump_line(); 71324453Smckusick ps.want_blank = false; 71424453Smckusick } 7158800Smckusick } 71624453Smckusick if (ps.in_parameter_declaration) 71724453Smckusick prefix_blankline_requested = 0; 7188800Smckusick 71924648Smckusick if (ps.p_l_follow > 0) { /* check for preceding 72024453Smckusick * unbalanced parens */ 72124453Smckusick diag(1, "Unbalanced parens"); 72224453Smckusick ps.p_l_follow = 0; 72324453Smckusick if (sp_sw) {/* check for unclosed if, for, etc. */ 7248800Smckusick sp_sw = false; 72524453Smckusick parse(hd_type); 72624453Smckusick ps.ind_level = ps.i_l_follow; 7278800Smckusick } 7288800Smckusick } 7298800Smckusick if (s_code == e_code) 73024453Smckusick ps.ind_stmt = false; /* dont put extra 73124453Smckusick * indentation on line 73224453Smckusick * with '{' */ 73324453Smckusick if (ps.in_decl && ps.in_or_st) { /* this is either a 73424453Smckusick * structure declaration 73524453Smckusick * or an init */ 73624453Smckusick di_stack[ps.dec_nest++] = dec_ind; 7378800Smckusick dec_ind = 0; 73824453Smckusick } else { 73924453Smckusick ps.decl_on_line = false; /* we cant be in the 74024453Smckusick * middle of a 74124453Smckusick * declaration, so dont do 74224453Smckusick * special indentation of 74324453Smckusick * comments */ 74424453Smckusick ps.in_parameter_declaration = 0; 7458800Smckusick } 74624453Smckusick parse(lbrace); /* let parser know about this */ 74724453Smckusick if (ps.want_blank) /* put a blank before '{' if '{' 74824453Smckusick * is not at start of line */ 7498800Smckusick *e_code++ = ' '; 75024453Smckusick ps.want_blank = false; 7518800Smckusick *e_code++ = '{'; 75224453Smckusick ps.just_saw_decl = 0; 7538800Smckusick break; 7548800Smckusick 75524453Smckusick case rbrace: /* got a '}' */ 75624453Smckusick if (ps.p_l_follow) { /* check for unclosed if, for, 75724453Smckusick * else. */ 75824453Smckusick diag(1, "Unbalanced parens"); 75924453Smckusick ps.p_l_follow = 0; 7608800Smckusick sp_sw = false; 7618800Smckusick } 76224453Smckusick ps.just_saw_decl = 0; 76324453Smckusick if (s_code != e_code && !ps.block_init) { /* '}' must be first on 76424453Smckusick * line */ 7658800Smckusick if (verbose) 76624453Smckusick diag(0, "Line broken"); 76724453Smckusick dump_line(); 7688800Smckusick } 7698800Smckusick *e_code++ = '}'; 77024453Smckusick ps.want_blank = true; 77124453Smckusick ps.in_stmt = ps.ind_stmt = false; 77224453Smckusick if (ps.dec_nest > 0) { /* we are in multi-level structure 77324453Smckusick * declaration */ 77424453Smckusick dec_ind = di_stack[--ps.dec_nest]; 77524453Smckusick if (ps.dec_nest == 0 && !ps.in_parameter_declaration) 77624453Smckusick ps.just_saw_decl = 2; 77724453Smckusick ps.in_decl = true; 7788800Smckusick } 77924453Smckusick prefix_blankline_requested = 0; 78024453Smckusick parse(rbrace); /* let parser know about this */ 78124453Smckusick ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead && ps.il[ps.tos] >= ps.ind_level; 78224453Smckusick if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0) 78324453Smckusick postfix_blankline_requested = 1; 7848800Smckusick break; 7858800Smckusick 78624453Smckusick case swstmt: /* got keyword "switch" */ 7878800Smckusick sp_sw = true; 78824453Smckusick hd_type = swstmt; /* keep this for when we have seen 78924453Smckusick * the expression */ 79024453Smckusick goto copy_id; /* go move the token into buffer */ 7918800Smckusick 79224453Smckusick case sp_paren: /* token is if, while, for */ 79324453Smckusick sp_sw = true; /* the interesting stuff is done after the 79424453Smckusick * expression is scanned */ 7958800Smckusick hd_type = (*token == 'i' ? ifstmt : 79624453Smckusick (*token == 'w' ? whilestmt : forstmt)); 7978800Smckusick 79824453Smckusick /* 79924453Smckusick * remember the type of header for later use by parser 80024453Smckusick */ 80124453Smckusick goto copy_id; /* copy the token into line */ 80224453Smckusick 80324453Smckusick case sp_nparen: /* got else, do */ 80424453Smckusick ps.in_stmt = false; 80524453Smckusick if (*token == 'e') { 80624453Smckusick if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) { 80724453Smckusick if (verbose) 80824453Smckusick diag(0, "Line broken"); 80924453Smckusick dump_line(); /* make sure this starts a line */ 81024453Smckusick ps.want_blank = false; 81124453Smckusick } 81224453Smckusick force_nl = true; /* also, following stuff must go 81324453Smckusick * onto new line */ 81424453Smckusick last_else = 1; 81524453Smckusick parse(elselit); 81624453Smckusick } else { 81724453Smckusick if (e_code != s_code) { /* make sure this starts a 81824453Smckusick * line */ 81924453Smckusick if (verbose) 82024453Smckusick diag(0, "Line broken"); 82124453Smckusick dump_line(); 82224453Smckusick ps.want_blank = false; 82324453Smckusick } 82424453Smckusick force_nl = true; /* also, following stuff must go 82524453Smckusick * onto new line */ 82624453Smckusick last_else = 0; 82724453Smckusick parse(dolit); 8288800Smckusick } 82924453Smckusick goto copy_id; /* move the token into line */ 8308800Smckusick 83124453Smckusick case decl: /* we have a declaration type (int, 83224453Smckusick * register, etc.) */ 83324453Smckusick parse(decl); /* let parser worry about indentation */ 83424453Smckusick if (ps.last_token == rparen && ps.tos <= 1) 83524453Smckusick ps.in_parameter_declaration = 1; 83624453Smckusick if (ps.in_parameter_declaration && ps.indent_parameters && ps.dec_nest == 0) { 83724453Smckusick ps.ind_level = ps.i_l_follow = 1; 83824453Smckusick ps.ind_stmt = 0; 83924453Smckusick } 84024453Smckusick ps.in_or_st = true; /* this might be a structure or 84124453Smckusick * initialization declaration */ 84224453Smckusick ps.in_decl = ps.decl_on_line = true; 84324453Smckusick if ( /* !ps.in_or_st && */ ps.dec_nest <= 0) 84424453Smckusick ps.just_saw_decl = 2; 84524453Smckusick prefix_blankline_requested = 0; 84624453Smckusick for (i = 0; token[i++];); /* get length of token */ 8478800Smckusick 84824453Smckusick /* 84924453Smckusick * dec_ind = e_code - s_code + (ps.decl_indent>i ? 85024453Smckusick * ps.decl_indent : i); 85124453Smckusick */ 85224453Smckusick dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i; 8538800Smckusick goto copy_id; 8548800Smckusick 85524453Smckusick case ident: /* got an identifier or constant */ 85624453Smckusick if (ps.in_decl) { /* if we are in a declaration, we 85724453Smckusick * must indent identifier */ 85824453Smckusick if (ps.want_blank) 8598800Smckusick *e_code++ = ' '; 86024453Smckusick ps.want_blank = false; 86124453Smckusick if (is_procname == 0 || !procnames_start_line) { 86224453Smckusick if (!ps.block_init) 86324453Smckusick if (troff && !ps.dumped_decl_indent) { 86424453Smckusick sprintf(e_code, "\\c\n.De %dp+\200p\n", dec_ind * 7); 86524453Smckusick ps.dumped_decl_indent = 1; 86624453Smckusick e_code += strlen(e_code); 86724453Smckusick } else 86824453Smckusick while ((e_code - s_code) < dec_ind) 86924453Smckusick *e_code++ = ' '; 87024453Smckusick } else { 87124453Smckusick if (dec_ind && s_code != e_code) 87224453Smckusick dump_line(); 87324453Smckusick dec_ind = 0; 87424453Smckusick ps.want_blank = false; 87524453Smckusick } 87624453Smckusick } else if (sp_sw && ps.p_l_follow == 0) { 87724453Smckusick sp_sw = false; 87824453Smckusick force_nl = true; 87924453Smckusick ps.last_u_d = true; 88024453Smckusick ps.in_stmt = false; 88124453Smckusick parse(hd_type); 8828800Smckusick } 88324453Smckusick copy_id: 88424453Smckusick if (ps.want_blank) 8858800Smckusick *e_code++ = ' '; 88624453Smckusick if (troff && ps.its_a_keyword) { 88724453Smckusick *e_code++ = BACKSLASH; 88824453Smckusick *e_code++ = 'f'; 88924453Smckusick *e_code++ = 'B'; 89024453Smckusick } 8918800Smckusick for (t_ptr = token; *t_ptr; ++t_ptr) 8928800Smckusick *e_code++ = *t_ptr; 89324453Smckusick if (troff && ps.its_a_keyword) { 89424453Smckusick *e_code++ = BACKSLASH; 89524453Smckusick *e_code++ = 'f'; 89624453Smckusick *e_code++ = 'R'; 89724453Smckusick } 89824453Smckusick ps.want_blank = true; 8998800Smckusick break; 9008800Smckusick 90124453Smckusick case period: /* treat a period kind of like a binary 90224453Smckusick * operation */ 90324453Smckusick *e_code++ = '.';/* move the period into line */ 90424453Smckusick ps.want_blank = false; /* dont put a blank after a period */ 9058800Smckusick break; 9068800Smckusick 90724453Smckusick case comma: 90824453Smckusick ps.want_blank = (s_code != e_code); /* only put blank after 90924453Smckusick * comma if comma does 91024453Smckusick * not start the line */ 91124453Smckusick if (ps.in_decl && is_procname == 0 && !ps.block_init) 9128800Smckusick while ((e_code - s_code) < (dec_ind - 1)) 9138800Smckusick *e_code++ = ' '; 9148800Smckusick 9158800Smckusick *e_code++ = ','; 91624453Smckusick if (ps.p_l_follow == 0) { 91724453Smckusick ps.block_init = 0; 91824453Smckusick if (break_comma && !ps.leave_comma) 91924453Smckusick force_nl = true; 92024453Smckusick } 9218800Smckusick break; 9228800Smckusick 92324453Smckusick case preesc: /* got the character '#' */ 92424453Smckusick if ((s_com != e_com) || 92524453Smckusick (s_lab != e_lab) || 92624453Smckusick (s_code != e_code)) 92724453Smckusick dump_line(); 92824453Smckusick *e_lab++ = '#'; /* move whole line to 'label' buffer */ 92924453Smckusick { 93024453Smckusick int in_comment = 0; 93124453Smckusick char *com_start = 0; 93224453Smckusick char quote = 0; 93324453Smckusick char *com_end = 0; 9348800Smckusick 93524453Smckusick while (*buf_ptr != '\n' || in_comment) { 93624453Smckusick *e_lab = *buf_ptr++; 93724453Smckusick if (buf_ptr >= buf_end) 93824453Smckusick fill_buffer(); 93924453Smckusick switch (*e_lab++) { 94024453Smckusick case BACKSLASH: 94124453Smckusick if (troff) 94224453Smckusick *e_lab++ = BACKSLASH; 94324453Smckusick if (!in_comment) { 94424453Smckusick *e_lab++ = *buf_ptr++; 94524453Smckusick if (buf_ptr >= buf_end) 94624453Smckusick fill_buffer(); 94724453Smckusick } 94824453Smckusick break; 94924453Smckusick case '/': 95024453Smckusick if (*buf_ptr == '*' && !in_comment && !quote) { 95124453Smckusick in_comment = 1; 95224453Smckusick *e_lab++ = *buf_ptr++; 95324453Smckusick com_start = e_lab - 2; 95424453Smckusick } 95524453Smckusick break; 95624453Smckusick case '"': 95724453Smckusick if (quote == '"') 95824453Smckusick quote = 0; 95924453Smckusick break; 96024453Smckusick case '\'': 96124453Smckusick if (quote == '\'') 96224453Smckusick quote = 0; 96324453Smckusick break; 96424453Smckusick case '*': 96524453Smckusick if (*buf_ptr == '/' && in_comment) { 96624453Smckusick in_comment = 0; 96724453Smckusick *e_lab++ = *buf_ptr++; 96824453Smckusick com_end = e_lab; 96924453Smckusick } 97024453Smckusick break; 97124453Smckusick } 9728800Smckusick } 97324453Smckusick while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 97424453Smckusick e_lab--; 97524453Smckusick if (e_lab == com_end && bp_save == 0) { /* comment on 97624453Smckusick * preprocessor line */ 97724453Smckusick if (sc_end == 0) /* if this is the first 97824453Smckusick * comment, we must set up 97924453Smckusick * the buffer */ 98024453Smckusick sc_end = &(save_com[0]); 98124453Smckusick else { 98224453Smckusick *sc_end++ = '\n'; /* add newline between 98324453Smckusick * comments */ 98424453Smckusick *sc_end++ = ' '; 98524453Smckusick --line_no; 98624453Smckusick } 98724453Smckusick bcopy(com_start, sc_end, com_end - com_start); 98824453Smckusick sc_end += com_end - com_start; 98924453Smckusick e_lab = com_start; 99024453Smckusick while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 99124453Smckusick e_lab--; 99224453Smckusick bp_save = buf_ptr; /* save current input 99324453Smckusick * buffer */ 99424453Smckusick be_save = buf_end; 99524453Smckusick buf_ptr = save_com; /* fix so that subsequent 99624453Smckusick * calls to lexi will take 99724453Smckusick * tokens out of save_com */ 99824453Smckusick *sc_end++ = ' '; /* add trailing blank, 99924453Smckusick * just in case */ 100024453Smckusick buf_end = sc_end; 100124453Smckusick sc_end = 0; 100224453Smckusick } 100324453Smckusick *e_lab = '\0'; /* null terminate line */ 100424453Smckusick ps.pcase = false; 10058800Smckusick } 100624453Smckusick if (strncmp(s_lab, "#if", 3) == 0) 100724453Smckusick if (ifdef_level < sizeof state_stack / sizeof state_stack[0]) { 100824453Smckusick match_state[ifdef_level].tos = -1; 100924453Smckusick state_stack[ifdef_level++] = ps; 101024453Smckusick } else 101124453Smckusick diag(1, "#if stack overflow"); 101224453Smckusick else if (strncmp(s_lab, "#else", 5) == 0) 101324453Smckusick if (ifdef_level <= 0) 101424453Smckusick diag(1, "Unmatched #else"); 101524453Smckusick else { 101624453Smckusick match_state[ifdef_level - 1] = ps; 101724453Smckusick ps = state_stack[ifdef_level - 1]; 101824453Smckusick } else if (strncmp(s_lab, "#endif", 6) == 0) 101924453Smckusick if (ifdef_level <= 0) 102024453Smckusick diag(1, "Unmatched #endif"); 102124453Smckusick else { 102224453Smckusick ifdef_level--; 102324453Smckusick #ifdef undef 10248800Smckusick 102524453Smckusick /* 102624453Smckusick * This match needs to be more intelligent before 102724453Smckusick * the message is useful 102824453Smckusick */ 102924453Smckusick if (match_state[ifdef_level].tos >= 0 103024453Smckusick && bcmp(&ps, &match_state[ifdef_level], sizeof ps)) 103124453Smckusick diag(0, "Syntactically inconsistant #ifdef alternatives."); 103224453Smckusick #endif 103324453Smckusick } 103424453Smckusick break; /* subsequent processing of the newline 103524453Smckusick * character will cause the line to be 103624453Smckusick * printed */ 10378800Smckusick 103824453Smckusick case comment: /* we have gotten a /* this is a biggie */ 103924453Smckusick proc_comment: 104024453Smckusick if (flushed_nl) { /* we should force a broken line 104124453Smckusick * here */ 104224453Smckusick flushed_nl = false; 104324453Smckusick dump_line(); 104424453Smckusick ps.want_blank = false; /* dont insert blank at 104524453Smckusick * line start */ 104624453Smckusick force_nl = false; 104724453Smckusick } 104824453Smckusick pr_comment(); 10498800Smckusick break; 105024453Smckusick } /* end of big switch stmt */ 105124453Smckusick *e_code = '\0'; /* make sure code section is null 105224453Smckusick * terminated */ 105324453Smckusick if (type_code != comment && type_code != newline && type_code != preesc) 105424453Smckusick ps.last_token = type_code; 105524453Smckusick } /* end of main while (1) loop */ 10568800Smckusick }; 10578800Smckusick 10588800Smckusick /* 105924648Smckusick * copy input file to backup file. If in_name is /blah/blah/blah/file, then 106024648Smckusick * backup file will be "file.BAK". Then make the backup file the input and 106124648Smckusick * original input file the output. 10628800Smckusick */ 106324453Smckusick bakcopy() 106424453Smckusick { 106524453Smckusick int n, 106624453Smckusick bakchn; 106724648Smckusick char buff[BUFSIZ]; 106824453Smckusick register char *p; 106924648Smckusick char *rindex(); 10708800Smckusick 107124648Smckusick if ((p = rindex(in_name, '/')) != NULL) 10728800Smckusick p++; 107324648Smckusick else 107424648Smckusick p = in_name; 107524453Smckusick sprintf(bakfile, "%s.BAK", p); 10768800Smckusick 107724453Smckusick /* copy in_name to backup file */ 107824453Smckusick bakchn = creat(bakfile, 0600); 10798800Smckusick if (bakchn < 0) { 108024648Smckusick fprintf(stderr, "indent: can't create backup file \"%s\"\n", bakfile); 108124648Smckusick exit(1); 10828800Smckusick } 108324648Smckusick while ((n = read(fileno(input), buff, sizeof buff)) > 0) 108424648Smckusick if (write(bakchn, buff, n) != n) { 108524648Smckusick fprintf(stderr, "indent: error writing backup file \"%s\"\n", 108624648Smckusick bakfile); 108724648Smckusick exit(1); 108824648Smckusick } 108924648Smckusick if (n < 0) { 109024648Smckusick fprintf(stderr, "indent: error reading input file \"%s\"\n", in_name); 109124648Smckusick exit(1); 109224648Smckusick } 109324453Smckusick close(bakchn); 109424453Smckusick fclose(input); 10958800Smckusick 109624453Smckusick /* re-open backup file as the input file */ 109724453Smckusick input = fopen(bakfile, "r"); 109824648Smckusick if (input == NULL) { 109924648Smckusick fprintf(stderr, "indent: can't re-open backup file\n"); 110024648Smckusick exit(1); 11018800Smckusick } 110224453Smckusick /* now the original input file will be the output */ 110324453Smckusick output = fopen(in_name, "w"); 110424648Smckusick if (output == NULL) { 110524648Smckusick fprintf(stderr, "indent: can't create %s\n", in_name); 110624453Smckusick unlink(bakfile); 110724648Smckusick exit(1); 11088800Smckusick } 11098800Smckusick } 1110