121968Sdist /* 221968Sdist * Copyright (c) 1980 Regents of the University of California. 321968Sdist * All rights reserved. The Berkeley software License Agreement 421968Sdist * specifies the terms and conditions for redistribution. 521968Sdist */ 68800Smckusick 721968Sdist #ifndef lint 821968Sdist char copyright[] = 921968Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 1021968Sdist All rights reserved.\n"; 1121968Sdist #endif not lint 1221968Sdist 1321968Sdist #ifndef lint 14*24453Smckusick static char sccsid[] = "@(#)indent.c 5.2 (Berkeley) 08/28/85"; 1521968Sdist #endif not lint 1621968Sdist 17*24453Smckusick /*- 18*24453Smckusick 19*24453Smckusick Copyright (C) 1976 20*24453Smckusick by the 21*24453Smckusick Board of Trustees 22*24453Smckusick of the 23*24453Smckusick University of Illinois 24*24453Smckusick 25*24453Smckusick All rights reserved 26*24453Smckusick 27*24453Smckusick 288800Smckusick NAME: 29*24453Smckusick indent main program 30*24453Smckusick 318800Smckusick FUNCTION: 32*24453Smckusick This is the main program of the indent program. Indent will take a C 33*24453Smckusick program source and reformat it into a semi-reasonable form. 34*24453Smckusick 358800Smckusick ALGORITHM: 36*24453Smckusick The routine lexi scans tokens and passes them back one at a time to the 37*24453Smckusick main routine. The subroutine parse takes care of much of the work of 38*24453Smckusick figuring indentation level. 39*24453Smckusick 40*24453Smckusick 1) Call lexi 41*24453Smckusick 2) Enter a monster switch statement on the code returned by lexi. If 42*24453Smckusick the indentation level for the line yet to be printed should be 43*24453Smckusick changed, set the variable ps.ind_level. If the indentation level for 44*24453Smckusick the following line should be changed, set the variable ps.i_l_follow. 458800Smckusick 46*24453Smckusick */ 478800Smckusick #include "indent_globs.h"; 488800Smckusick #include "indent_codes.h"; 498800Smckusick 50*24453Smckusick char *in_name = "Standard Input"; /* will always point to name of 51*24453Smckusick * input file */ 52*24453Smckusick char *out_name = "Standard Output"; /* will always point to 53*24453Smckusick * name of output file */ 54*24453Smckusick char bakfile[32] = ""; 558800Smckusick 56*24453Smckusick main(argc, argv) 57*24453Smckusick int argc; 58*24453Smckusick char **argv; 598800Smckusick { 608800Smckusick 61*24453Smckusick int dec_ind; /* current indentation for declarations */ 62*24453Smckusick int di_stack[20]; /* a stack of structure indentation levels */ 63*24453Smckusick int flushed_nl; /* used when buffering up comments to 64*24453Smckusick * remember that a newline was passed over */ 65*24453Smckusick int force_nl; /* when true, code must be broken */ 66*24453Smckusick int hd_type; /* used to store type of stmt for if 67*24453Smckusick * (...), for (...), etc */ 68*24453Smckusick register int i; /* local loop counter */ 69*24453Smckusick register int j; /* local loop counter */ 70*24453Smckusick int scase; /* set to true when we see a case, so we 71*24453Smckusick * will know what to do with the following 72*24453Smckusick * colon */ 73*24453Smckusick int sp_sw; /* when true, we are in the expressin of 74*24453Smckusick * if(...), while(...), etc. */ 75*24453Smckusick int squest; /* when this is positive, we have seen a ? 76*24453Smckusick * without the matching : in a <c>?<s>:<s> 77*24453Smckusick * construct */ 78*24453Smckusick register char *t_ptr; /* used for copying tokens */ 79*24453Smckusick int type_code; /* the type of token, returned by lexi */ 808800Smckusick 81*24453Smckusick int last_else = 0; /* true iff last keyword was an else */ 828800Smckusick 838800Smckusick 84*24453Smckusick /*-----------------------------------------------*\ 85*24453Smckusick | INITIALIZATION | 868800Smckusick \*-----------------------------------------------*/ 878800Smckusick 888800Smckusick 89*24453Smckusick ps.p_stack[0] = stmt; /* this is the parser's stack */ 90*24453Smckusick ps.last_nl = true; /* this is true if the last thing scanned 91*24453Smckusick * was a newline */ 92*24453Smckusick ps.last_token = semicolon; 93*24453Smckusick combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and 94*24453Smckusick * comment buffers */ 958800Smckusick combuf[1] = codebuf[1] = labbuf[1] = '\0'; 96*24453Smckusick ps.else_if = 1; /* Default else-if special processing to 97*24453Smckusick * on */ 988800Smckusick s_lab = e_lab = labbuf + 1; 998800Smckusick s_code = e_code = codebuf + 1; 1008800Smckusick s_com = e_com = combuf + 1; 1018800Smckusick 1028800Smckusick buf_ptr = buf_end = in_buffer; 1038800Smckusick line_no = 1; 104*24453Smckusick had_eof = ps.in_decl = ps.decl_on_line = break_comma = false; 1058800Smckusick sp_sw = force_nl = false; 106*24453Smckusick ps.in_or_st = false; 107*24453Smckusick ps.bl_line = true; 1088800Smckusick dec_ind = 0; 109*24453Smckusick di_stack[ps.dec_nest = 0] = 0; 110*24453Smckusick ps.want_blank = ps.in_stmt = ps.ind_stmt = false; 1118800Smckusick 1128800Smckusick 113*24453Smckusick scase = ps.pcase = false; 1148800Smckusick squest = 0; 1158800Smckusick sc_end = 0; 1168800Smckusick bp_save = 0; 1178800Smckusick be_save = 0; 1188800Smckusick 119*24453Smckusick output = 0; 1208800Smckusick 1218800Smckusick 1228800Smckusick 123*24453Smckusick /*--------------------------------------------------*\ 1248800Smckusick | COMMAND LINE SCAN 125*24453Smckusick \*-------------------------------------------------- 126*24453Smckusick */ 1278800Smckusick 128*24453Smckusick max_col = 78; /* -l78 */ 129*24453Smckusick lineup_to_parens = 1; /* -lp */ 130*24453Smckusick ps.ljust_decl = 0; /* -ndj */ 131*24453Smckusick ps.com_ind = 33; /* -c33 */ 132*24453Smckusick star_comment_cont = 1; /* -sc */ 133*24453Smckusick ps.ind_size = 8; /* -i8 */ 134*24453Smckusick verbose = 0; 135*24453Smckusick ps.decl_indent = 16; /* -di16 */ 136*24453Smckusick ps.indent_parameters = 1; /* -ip */ 137*24453Smckusick ps.decl_com_ind = 0; /* if this is not set to some positive 138*24453Smckusick * value by an arg, we will set this equal 139*24453Smckusick * to ps.com_ind */ 140*24453Smckusick btype_2 = 1; /* -br */ 141*24453Smckusick cuddle_else = 1; /* -ce */ 142*24453Smckusick ps.unindent_displace = 0; /* -d0 */ 143*24453Smckusick ps.case_indent = 0; /* -cli0 */ 144*24453Smckusick format_col1_comments = 1; /* -fc1 */ 145*24453Smckusick procnames_start_line = 1; /* -psl */ 146*24453Smckusick proc_calls_space = 0; /* -npcs */ 147*24453Smckusick comment_delimiter_on_blankline = 1; /* -cdb */ 148*24453Smckusick ps.leave_comma = 1; /* -nbc */ 1498800Smckusick 150*24453Smckusick for (i = 1; i < argc; ++i) 151*24453Smckusick if (strcmp(argv[i], "-npro") == 0) 152*24453Smckusick break; 153*24453Smckusick if (i >= argc) 154*24453Smckusick set_profile(); 1558800Smckusick 1568800Smckusick for (i = 1; i < argc; ++i) { 157*24453Smckusick 158*24453Smckusick /* 159*24453Smckusick * look thru args (if any) for changes to defaults 160*24453Smckusick */ 1618800Smckusick if (argv[i][0] != '-') {/* no flag on parameter */ 162*24453Smckusick if (input == 0) { /* we must have the input file */ 163*24453Smckusick in_name = argv[i]; /* remember name of input file */ 164*24453Smckusick input = fopen(in_name, "r"); 165*24453Smckusick if (input == 0) { /* check for open error */ 166*24453Smckusick printf("Can't open %s\n", argv[i]); 167*24453Smckusick exit(); 1688800Smckusick } 1698800Smckusick continue; 170*24453Smckusick } else if (output == 0) { /* we have the output file */ 171*24453Smckusick out_name = argv[i]; /* remember name of output file */ 172*24453Smckusick if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite 173*24453Smckusick * the file */ 174*24453Smckusick printf("Input and output files must be different\n"); 175*24453Smckusick exit(); 176*24453Smckusick } 177*24453Smckusick output = fopen(out_name, "w"); 178*24453Smckusick if (output == 0) { /* check for create error */ 179*24453Smckusick printf("Can't create %s\n", argv[i]); 180*24453Smckusick exit(); 181*24453Smckusick } 182*24453Smckusick continue; 1838800Smckusick } 184*24453Smckusick printf("Unknown parameter: %s\n", argv[i]); 185*24453Smckusick exit(); 186*24453Smckusick } else 187*24453Smckusick set_option(argv[i]); 1888800Smckusick 189*24453Smckusick } /* end of for */ 190*24453Smckusick if (input == 0) { 191*24453Smckusick printf("Usage: indent file [ outfile ] [ options ]\n"); 192*24453Smckusick exit(); 193*24453Smckusick } 194*24453Smckusick if (output == 0) 195*24453Smckusick if (troff) 196*24453Smckusick output = stdout; 197*24453Smckusick else { 198*24453Smckusick out_name = in_name; 199*24453Smckusick bakcopy(); 2008800Smckusick } 201*24453Smckusick if (ps.com_ind <= 1) 202*24453Smckusick ps.com_ind = 2; /* dont put normal comments before column 203*24453Smckusick * 2 */ 204*24453Smckusick if (block_comment_max_col <= 0) 205*24453Smckusick block_comment_max_col = max_col; 206*24453Smckusick if (ps.decl_com_ind <= 0) /* if not specified by user, set this */ 207*24453Smckusick ps.decl_com_ind = ps.ljust_decl ? (ps.com_ind <= 10 ? 2 : ps.com_ind - 8) : ps.com_ind; 208*24453Smckusick if (continuation_indent == 0) 209*24453Smckusick continuation_indent = ps.ind_size; 210*24453Smckusick fill_buffer(); /* get first batch of stuff into input 211*24453Smckusick * buffer */ 2128800Smckusick 213*24453Smckusick parse(semicolon); 214*24453Smckusick { 215*24453Smckusick register char *p = buf_ptr; 216*24453Smckusick register col = 1; 2178800Smckusick 218*24453Smckusick while (1) { 219*24453Smckusick if (*p == ' ') 220*24453Smckusick col++; 221*24453Smckusick else if (*p == '\t') 222*24453Smckusick col = ((col - 1) & ~7) + 9; 223*24453Smckusick else 224*24453Smckusick break; 225*24453Smckusick p++; 226*24453Smckusick }; 227*24453Smckusick if (col > ps.ind_size) 228*24453Smckusick ps.ind_level = ps.i_l_follow = col / ps.ind_size; 2298800Smckusick } 230*24453Smckusick if (troff) { 231*24453Smckusick register char *p = in_name, 232*24453Smckusick *beg = in_name; 233*24453Smckusick 234*24453Smckusick while (*p) 235*24453Smckusick if (*p++ == '/') 236*24453Smckusick beg = p; 237*24453Smckusick fprintf(output, ".Fn \"%s\"\n", beg); 2388800Smckusick } 2398800Smckusick 240*24453Smckusick /* 241*24453Smckusick * START OF MAIN LOOP 242*24453Smckusick */ 2438800Smckusick 244*24453Smckusick while (1) { /* this is the main loop. it will go 245*24453Smckusick * until we reach eof */ 246*24453Smckusick int is_procname; 2478800Smckusick 248*24453Smckusick type_code = lexi(); /* lexi reads one token. The actual 249*24453Smckusick * characters read are stored in "token". 250*24453Smckusick * lexi returns a code indicating the type 251*24453Smckusick * of token */ 252*24453Smckusick is_procname = ps.procname[0]; 2538800Smckusick 254*24453Smckusick /* 255*24453Smckusick * The following code moves everything following an if (), while 256*24453Smckusick * (), else, etc. up to the start of the following stmt to a 257*24453Smckusick * buffer. This allows proper handling of both kinds of brace 258*24453Smckusick * placement. 259*24453Smckusick */ 2608800Smckusick 2618800Smckusick flushed_nl = false; 262*24453Smckusick while (ps.search_brace) { /* if we scanned an if(), while(), 263*24453Smckusick * etc., we might need to copy 264*24453Smckusick * stuff into a buffer we must 265*24453Smckusick * loop, copying stuff into 266*24453Smckusick * save_com, until we find the 267*24453Smckusick * start of the stmt which follows 268*24453Smckusick * the if, or whatever */ 2698800Smckusick switch (type_code) { 270*24453Smckusick case newline: 2718800Smckusick ++line_no; 2728800Smckusick flushed_nl = true; 273*24453Smckusick case form_feed: 274*24453Smckusick break; /* form feeds and newlines found here will 275*24453Smckusick * be ignored */ 2768800Smckusick 277*24453Smckusick case lbrace: /* this is a brace that starts the 278*24453Smckusick * compound stmt */ 279*24453Smckusick if (sc_end == 0) { /* ignore buffering if a comment 280*24453Smckusick * wasnt stored up */ 281*24453Smckusick ps.search_brace = false; 2828800Smckusick goto check_type; 2838800Smckusick } 2848800Smckusick if (btype_2) { 285*24453Smckusick save_com[0] = '{'; /* we either want to put 286*24453Smckusick * the brace right after 287*24453Smckusick * the if */ 288*24453Smckusick goto sw_buffer; /* go to common code to get out of 289*24453Smckusick * this loop */ 2908800Smckusick } 291*24453Smckusick case comment: /* we have a comment, so we must copy it 292*24453Smckusick * into the buffer */ 293*24453Smckusick if (!flushed_nl) { 294*24453Smckusick if (sc_end == 0) { /* if this is the first 295*24453Smckusick * comment, we must set up 296*24453Smckusick * the buffer */ 297*24453Smckusick save_com[0] = save_com[1] = ' '; 298*24453Smckusick sc_end = &(save_com[2]); 299*24453Smckusick } else { 300*24453Smckusick *sc_end++ = '\n'; /* add newline between 301*24453Smckusick * comments */ 302*24453Smckusick *sc_end++ = ' '; 303*24453Smckusick --line_no; 304*24453Smckusick } 305*24453Smckusick *sc_end++ = '/'; /* copy in start of 306*24453Smckusick * comment */ 307*24453Smckusick *sc_end++ = '*'; 3088800Smckusick 309*24453Smckusick for (;;) { /* loop until we get to the end of 310*24453Smckusick * the comment */ 311*24453Smckusick *sc_end = *buf_ptr++; 312*24453Smckusick if (buf_ptr >= buf_end) 313*24453Smckusick fill_buffer(); 314*24453Smckusick 315*24453Smckusick if (*sc_end++ == '*' && *buf_ptr == '/') 316*24453Smckusick break; /* we are at end of comment */ 317*24453Smckusick 318*24453Smckusick if (sc_end >= &(save_com[sc_size])) { /* check for temp buffer 319*24453Smckusick * overflow */ 320*24453Smckusick diag(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever."); 321*24453Smckusick fflush(output); 322*24453Smckusick exit(); 323*24453Smckusick } 324*24453Smckusick } 325*24453Smckusick *sc_end++ = '/'; /* add ending slash */ 326*24453Smckusick if (++buf_ptr >= buf_end) /* get past / in buffer */ 327*24453Smckusick fill_buffer(); 328*24453Smckusick break; 329*24453Smckusick } 330*24453Smckusick default: /* it is the start of a normal statment */ 331*24453Smckusick if (flushed_nl) /* if we flushed a newline, make 332*24453Smckusick * sure it is put back */ 3338800Smckusick force_nl = true; 334*24453Smckusick if (type_code == sp_paren && *token == 'i' 335*24453Smckusick && last_else && ps.else_if 336*24453Smckusick || type_code == sp_nparen && *token == 'e' 337*24453Smckusick && e_code != s_code && e_code[-1] == '}') 338*24453Smckusick force_nl = false; 3398800Smckusick 340*24453Smckusick if (sc_end == 0) { /* ignore buffering if comment 341*24453Smckusick * wasnt saved up */ 342*24453Smckusick ps.search_brace = false; 3438800Smckusick goto check_type; 3448800Smckusick } 345*24453Smckusick if (force_nl) { /* if we should insert a nl here, 346*24453Smckusick * put it into the buffer */ 3478800Smckusick force_nl = false; 348*24453Smckusick --line_no; /* this will be re-increased when 349*24453Smckusick * the nl is read from the buffer */ 3508800Smckusick *sc_end++ = '\n'; 3518800Smckusick *sc_end++ = ' '; 352*24453Smckusick if (verbose && !flushed_nl) /* print error msg if 353*24453Smckusick * the line was not 354*24453Smckusick * already broken */ 355*24453Smckusick diag(0, "Line broken"); 3568800Smckusick flushed_nl = false; 3578800Smckusick } 3588800Smckusick for (t_ptr = token; *t_ptr; ++t_ptr) 359*24453Smckusick *sc_end++ = *t_ptr; /* copy token into temp 360*24453Smckusick * buffer */ 3618800Smckusick 362*24453Smckusick sw_buffer: 363*24453Smckusick ps.search_brace = false; /* stop looking for start 364*24453Smckusick * of stmt */ 365*24453Smckusick bp_save = buf_ptr; /* save current input buffer */ 3668800Smckusick be_save = buf_end; 367*24453Smckusick buf_ptr = save_com; /* fix so that subsequent calls to 368*24453Smckusick * lexi will take tokens out of 369*24453Smckusick * save_com */ 370*24453Smckusick *sc_end++ = ' '; /* add trailing blank, just in 371*24453Smckusick * case */ 3728800Smckusick buf_end = sc_end; 3738800Smckusick sc_end = 0; 3748800Smckusick break; 375*24453Smckusick } /* end of switch */ 376*24453Smckusick if (type_code != 0) /* we must make this check, just in case 377*24453Smckusick * there was an unexpected EOF */ 378*24453Smckusick type_code = lexi(); /* read another token */ 379*24453Smckusick is_procname = ps.procname[0]; 380*24453Smckusick } /* end of while (serach_brace) */ 381*24453Smckusick last_else = 0; 382*24453Smckusick check_type: 383*24453Smckusick if (type_code == 0) { /* we got eof */ 3848800Smckusick if (s_lab != e_lab || s_code != e_code 385*24453Smckusick || s_com != e_com) /* must dump end of line */ 386*24453Smckusick dump_line(); 387*24453Smckusick if (ps.tos > 1) /* check for balanced braces */ 388*24453Smckusick diag(1, "Stuff missing from end of file."); 3898800Smckusick 3908800Smckusick if (verbose) { 391*24453Smckusick printf("There were %d output lines and %d comments\n", 392*24453Smckusick ps.out_lines, ps.out_coms); 393*24453Smckusick printf("(Lines with comments)/(Lines with code): %6.3f\n", 394*24453Smckusick (1.0 * ps.com_lines) / code_lines); 3958800Smckusick } 396*24453Smckusick fflush(output); 397*24453Smckusick exit(); 3988800Smckusick } 3998800Smckusick if ( 400*24453Smckusick (type_code != comment) && 401*24453Smckusick (type_code != newline) && 402*24453Smckusick (type_code != preesc) && 403*24453Smckusick (type_code != form_feed)) { 4048800Smckusick if ( 405*24453Smckusick force_nl 406*24453Smckusick && 407*24453Smckusick (type_code != semicolon) && 408*24453Smckusick ( 409*24453Smckusick type_code != lbrace 410*24453Smckusick || 411*24453Smckusick !btype_2 412*24453Smckusick )) { /* we should force a broken line here */ 4138800Smckusick if (verbose && !flushed_nl) 414*24453Smckusick diag(0, "Line broken"); 4158800Smckusick flushed_nl = false; 416*24453Smckusick dump_line(); 417*24453Smckusick ps.want_blank = false; /* dont insert blank at line start */ 4188800Smckusick force_nl = false; 4198800Smckusick } 420*24453Smckusick ps.in_stmt = true; /* turn on flag which causes an extra 421*24453Smckusick * level of indentation. this is turned 422*24453Smckusick * off by a ; or '}' */ 423*24453Smckusick if (s_com != e_com) { /* the turkey has embedded a 424*24453Smckusick * comment in a line. fix it */ 4258800Smckusick *e_code++ = ' '; 4268800Smckusick for (t_ptr = s_com; *t_ptr; ++t_ptr) 4278800Smckusick *e_code++ = *t_ptr; 4288800Smckusick *e_code++ = ' '; 429*24453Smckusick *e_code = '\0'; /* null terminate code sect */ 430*24453Smckusick ps.want_blank = false; 4318800Smckusick e_com = s_com; 4328800Smckusick } 433*24453Smckusick } else if (type_code != comment) /* preserve force_nl thru 434*24453Smckusick * a comment */ 435*24453Smckusick force_nl = false; 4368800Smckusick 437*24453Smckusick /* 438*24453Smckusick * cancel forced newline after newline, form feed, etc 439*24453Smckusick */ 4408800Smckusick 4418800Smckusick 4428800Smckusick 443*24453Smckusick /*----------------------------------------------------*\ 444*24453Smckusick | do switch on type of token scanned 445*24453Smckusick \*----------------------------------------------------*/ 446*24453Smckusick switch (type_code) { /* now, decide what to do with the token */ 447*24453Smckusick 448*24453Smckusick case form_feed: /* found a form feed in line */ 449*24453Smckusick ps.use_ff = true; /* a form feed is treated much 450*24453Smckusick * like a newline */ 451*24453Smckusick dump_line(); 452*24453Smckusick ps.want_blank = false; 4538800Smckusick break; 4548800Smckusick 455*24453Smckusick case newline: 456*24453Smckusick if (ps.last_token != comma || ps.p_l_follow > 0 457*24453Smckusick || !ps.leave_comma || !break_comma || s_com != e_com) { 458*24453Smckusick dump_line(); 459*24453Smckusick ps.want_blank = false; 460*24453Smckusick } 461*24453Smckusick ++line_no; /* keep track of input line number */ 4628800Smckusick break; 4638800Smckusick 464*24453Smckusick case lparen: /* got a '(' or '[' */ 465*24453Smckusick ++ps.p_l_follow;/* count parens to make Healy happy */ 466*24453Smckusick if (ps.want_blank && *token != '[' && 467*24453Smckusick (ps.last_token != ident || proc_calls_space 468*24453Smckusick || (ps.its_a_keyword && !ps.sizeof_keyword))) 4698800Smckusick *e_code++ = ' '; 470*24453Smckusick if (ps.in_decl && !ps.block_init) 471*24453Smckusick if (troff && !ps.dumped_decl_indent) { 472*24453Smckusick ps.dumped_decl_indent = 1; 473*24453Smckusick sprintf(e_code, "\\c\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); 474*24453Smckusick e_code += strlen(e_code); 475*24453Smckusick } else { 476*24453Smckusick while ((e_code - s_code) < dec_ind) 477*24453Smckusick *e_code++ = ' '; 478*24453Smckusick *e_code++ = token[0]; 479*24453Smckusick } else 480*24453Smckusick *e_code++ = token[0]; 481*24453Smckusick ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code; 482*24453Smckusick ps.want_blank = false; 483*24453Smckusick if (ps.in_or_st && *token == '(') { 4848800Smckusick 485*24453Smckusick /* 486*24453Smckusick * this is a kluge to make sure that declarations will 487*24453Smckusick * be aligned right if proc decl has an explicit type 488*24453Smckusick * on it, i.e. "int a(x) {..." 489*24453Smckusick */ 490*24453Smckusick parse(semicolon); /* I said this was a kluge... */ 491*24453Smckusick ps.in_or_st = false; /* turn off flag for 492*24453Smckusick * structure decl or 493*24453Smckusick * initialization */ 4948800Smckusick } 495*24453Smckusick if (ps.sizeof_keyword) ps.sizeof_mask |= 1<<ps.p_l_follow; 4968800Smckusick break; 4978800Smckusick 498*24453Smckusick case rparen: /* got a ')' or ']' */ 499*24453Smckusick if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask) { 500*24453Smckusick ps.last_u_d = true; 501*24453Smckusick ps.cast_mask &= (1 << ps.p_l_follow) - 1; 5028800Smckusick } 503*24453Smckusick ps.sizeof_mask &= (1 << ps.p_l_follow) - 1; 504*24453Smckusick if (--ps.p_l_follow < 0) { 505*24453Smckusick ps.p_l_follow = 0; 506*24453Smckusick diag(0, "Extra %c", *token); 507*24453Smckusick } 508*24453Smckusick if (e_code == s_code) /* if the paren starts the line */ 509*24453Smckusick ps.paren_level = ps.p_l_follow; /* then indent it */ 5108800Smckusick 5118800Smckusick *e_code++ = token[0]; 512*24453Smckusick ps.want_blank = true; 5138800Smckusick 514*24453Smckusick if (sp_sw && (ps.p_l_follow == 0)) { /* check for end of if 515*24453Smckusick * (...), or some such */ 5168800Smckusick sp_sw = false; 517*24453Smckusick force_nl = true; /* must force newline after if */ 518*24453Smckusick ps.last_u_d = true; /* inform lexi that a following 519*24453Smckusick * operator is unary */ 520*24453Smckusick ps.in_stmt = false; /* dont use stmt continuation 521*24453Smckusick * indentation */ 5228800Smckusick 523*24453Smckusick parse(hd_type); /* let parser worry about if, or 524*24453Smckusick * whatever */ 5258800Smckusick } 526*24453Smckusick ps.search_brace = btype_2; /* this should insure that 527*24453Smckusick * constructs such as 528*24453Smckusick * main(){...} and 529*24453Smckusick * int[]{...} have their 530*24453Smckusick * braces put in the right 531*24453Smckusick * place */ 5328800Smckusick break; 5338800Smckusick 534*24453Smckusick case unary_op: /* this could be any unary operation */ 535*24453Smckusick if (ps.want_blank) 5368800Smckusick *e_code++ = ' '; 5378800Smckusick 538*24453Smckusick if (troff && !ps.dumped_decl_indent && ps.in_decl) { 539*24453Smckusick sprintf(e_code, "\\c\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); 540*24453Smckusick ps.dumped_decl_indent = 1; 541*24453Smckusick e_code += strlen(e_code); 542*24453Smckusick } else { 543*24453Smckusick char *res = token; 544*24453Smckusick 545*24453Smckusick if (ps.in_decl && !ps.block_init) { /* if this is a unary op 546*24453Smckusick * in a declaration, we 547*24453Smckusick * should indent this 548*24453Smckusick * token */ 549*24453Smckusick for (i = 0; token[i]; ++i); /* find length of token */ 550*24453Smckusick while ((e_code - s_code) < (dec_ind - i)) 551*24453Smckusick *e_code++ = ' '; /* pad it */ 552*24453Smckusick } 553*24453Smckusick if (troff && token[0] == '-' && token[1] == '>') 554*24453Smckusick res = "\\(->"; 555*24453Smckusick for (t_ptr = res; *t_ptr; ++t_ptr) 556*24453Smckusick *e_code++ = *t_ptr; 5578800Smckusick } 558*24453Smckusick ps.want_blank = false; 5598800Smckusick break; 5608800Smckusick 561*24453Smckusick case binary_op: /* any binary operation */ 562*24453Smckusick do_binary: 563*24453Smckusick if (ps.want_blank) 5648800Smckusick *e_code++ = ' '; 565*24453Smckusick { 566*24453Smckusick char *res = token; 567*24453Smckusick 568*24453Smckusick if (troff) 569*24453Smckusick switch (token[0]) { 570*24453Smckusick case '<': 571*24453Smckusick if (token[1] == '=') 572*24453Smckusick res = "\\(<="; 573*24453Smckusick break; 574*24453Smckusick case '>': 575*24453Smckusick if (token[1] == '=') 576*24453Smckusick res = "\\(>="; 577*24453Smckusick break; 578*24453Smckusick case '!': 579*24453Smckusick if (token[1] == '=') 580*24453Smckusick res = "\\(!="; 581*24453Smckusick break; 582*24453Smckusick case '|': 583*24453Smckusick if (token[1] == '|') 584*24453Smckusick res = "\\(br\\(br"; 585*24453Smckusick else if (token[1] == 0) 586*24453Smckusick res = "\\(br"; 587*24453Smckusick break; 588*24453Smckusick } 589*24453Smckusick for (t_ptr = res; *t_ptr; ++t_ptr) 590*24453Smckusick *e_code++ = *t_ptr; /* move the operator */ 591*24453Smckusick } 592*24453Smckusick ps.want_blank = true; 5938800Smckusick break; 5948800Smckusick 595*24453Smckusick case postop: /* got a trailing ++ or -- */ 5968800Smckusick *e_code++ = token[0]; 5978800Smckusick *e_code++ = token[1]; 598*24453Smckusick ps.want_blank = true; 5998800Smckusick break; 6008800Smckusick 601*24453Smckusick case question: /* got a ? */ 602*24453Smckusick squest++; /* this will be used when a later colon 603*24453Smckusick * appears so we can distinguish the 604*24453Smckusick * <c>?<n>:<n> construct */ 605*24453Smckusick if (ps.want_blank) 6068800Smckusick *e_code++ = ' '; 6078800Smckusick *e_code++ = '?'; 608*24453Smckusick ps.want_blank = true; 6098800Smckusick break; 6108800Smckusick 611*24453Smckusick case casestmt: /* got word 'case' or 'default' */ 612*24453Smckusick scase = true; /* so we can process the later colon 613*24453Smckusick * properly */ 614*24453Smckusick goto copy_id; 6158800Smckusick 616*24453Smckusick case colon: /* got a ':' */ 617*24453Smckusick if (squest > 0) { /* it is part of the <c>?<n>: <n> 618*24453Smckusick * construct */ 6198800Smckusick --squest; 620*24453Smckusick if (ps.want_blank) 6218800Smckusick *e_code++ = ' '; 6228800Smckusick *e_code++ = ':'; 623*24453Smckusick ps.want_blank = true; 6248800Smckusick break; 6258800Smckusick } 626*24453Smckusick if (ps.in_decl) { 627*24453Smckusick *e_code++ = ':'; 628*24453Smckusick ps.want_blank = false; 629*24453Smckusick break; 630*24453Smckusick } 631*24453Smckusick ps.in_stmt = false; /* seeing a label does not imply 632*24453Smckusick * we are in a stmt */ 6338800Smckusick for (t_ptr = s_code; *t_ptr; ++t_ptr) 634*24453Smckusick *e_lab++ = *t_ptr; /* turn everything so far into a 635*24453Smckusick * label */ 6368800Smckusick e_code = s_code; 6378800Smckusick *e_lab++ = ':'; 6388800Smckusick *e_lab++ = ' '; 6398800Smckusick *e_lab = '\0'; 6408800Smckusick 641*24453Smckusick force_nl = ps.pcase = scase; /* ps.pcase will be used 642*24453Smckusick * by dump_line to decide 643*24453Smckusick * how to indent the 644*24453Smckusick * label. force_nl will 645*24453Smckusick * force a case n: to be 646*24453Smckusick * on a line by itself */ 6478800Smckusick scase = false; 648*24453Smckusick ps.want_blank = false; 6498800Smckusick break; 6508800Smckusick 651*24453Smckusick case semicolon: /* got a ';' */ 652*24453Smckusick ps.in_or_st = false; /* we are not in an initialization 653*24453Smckusick * or structure declaration */ 654*24453Smckusick scase = false; /* these will only need resetting in a 655*24453Smckusick * error */ 6568800Smckusick squest = 0; 657*24453Smckusick if (ps.last_token == rparen) 658*24453Smckusick ps.in_parameter_declaration = 0; 659*24453Smckusick ps.cast_mask = 0; 660*24453Smckusick ps.sizeof_mask = 0; 661*24453Smckusick ps.block_init = 0; 662*24453Smckusick ps.just_saw_decl--; 6638800Smckusick 664*24453Smckusick if (ps.in_decl && s_code == e_code && !ps.block_init) 6658800Smckusick while ((e_code - s_code) < (dec_ind - 1)) 6668800Smckusick *e_code++ = ' '; 6678800Smckusick 668*24453Smckusick ps.in_decl = (ps.dec_nest > 0); /* if we were in a first 669*24453Smckusick * level structure 670*24453Smckusick * declaration, we arent 671*24453Smckusick * any more */ 6728800Smckusick 673*24453Smckusick if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) { 674*24453Smckusick 675*24453Smckusick /* 676*24453Smckusick * This should be true iff there were unbalanced 677*24453Smckusick * parens in the stmt. It is a bit complicated, 678*24453Smckusick * because the semicolon might be in a for stmt 679*24453Smckusick */ 680*24453Smckusick diag(1, "Unbalanced parens"); 681*24453Smckusick ps.p_l_follow = 0; 682*24453Smckusick if (sp_sw) {/* this is a check for a if, while, etc. 683*24453Smckusick * with unbalanced parens */ 6848800Smckusick sp_sw = false; 685*24453Smckusick parse(hd_type); /* dont lose the if, or whatever */ 6868800Smckusick } 6878800Smckusick } 6888800Smckusick *e_code++ = ';'; 689*24453Smckusick ps.want_blank = true; 690*24453Smckusick ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in 691*24453Smckusick * the middle of a stmt */ 6928800Smckusick 693*24453Smckusick if (!sp_sw) { /* if not if for (;;) */ 694*24453Smckusick parse(semicolon); /* let parser know about end of 695*24453Smckusick * stmt */ 696*24453Smckusick force_nl = true; /* force newline after a end of 697*24453Smckusick * stmt */ 6988800Smckusick } 6998800Smckusick break; 7008800Smckusick 701*24453Smckusick case lbrace: /* got a '{' */ 702*24453Smckusick ps.in_stmt = false; /* dont indent the {} */ 703*24453Smckusick if (!ps.block_init) 704*24453Smckusick force_nl = true; /* force other stuff on same line 705*24453Smckusick * as '{' onto new line */ 7068800Smckusick 707*24453Smckusick if (s_code != e_code && !ps.block_init) { 708*24453Smckusick if (!btype_2) { 709*24453Smckusick dump_line(); 710*24453Smckusick ps.want_blank = false; 711*24453Smckusick } else if (ps.in_parameter_declaration && !ps.in_or_st) { 712*24453Smckusick ps.i_l_follow = 0; 713*24453Smckusick dump_line(); 714*24453Smckusick ps.want_blank = false; 715*24453Smckusick } 7168800Smckusick } 717*24453Smckusick if (ps.in_parameter_declaration) 718*24453Smckusick prefix_blankline_requested = 0; 7198800Smckusick 720*24453Smckusick if (ps.p_l_follow > 0) { /* check for preceeding 721*24453Smckusick * unbalanced parens */ 722*24453Smckusick diag(1, "Unbalanced parens"); 723*24453Smckusick ps.p_l_follow = 0; 724*24453Smckusick if (sp_sw) {/* check for unclosed if, for, etc. */ 7258800Smckusick sp_sw = false; 726*24453Smckusick parse(hd_type); 727*24453Smckusick ps.ind_level = ps.i_l_follow; 7288800Smckusick } 7298800Smckusick } 7308800Smckusick if (s_code == e_code) 731*24453Smckusick ps.ind_stmt = false; /* dont put extra 732*24453Smckusick * indentation on line 733*24453Smckusick * with '{' */ 734*24453Smckusick if (ps.in_decl && ps.in_or_st) { /* this is either a 735*24453Smckusick * structure declaration 736*24453Smckusick * or an init */ 737*24453Smckusick di_stack[ps.dec_nest++] = dec_ind; 7388800Smckusick dec_ind = 0; 739*24453Smckusick } else { 740*24453Smckusick ps.decl_on_line = false; /* we cant be in the 741*24453Smckusick * middle of a 742*24453Smckusick * declaration, so dont do 743*24453Smckusick * special indentation of 744*24453Smckusick * comments */ 745*24453Smckusick ps.in_parameter_declaration = 0; 7468800Smckusick } 747*24453Smckusick parse(lbrace); /* let parser know about this */ 748*24453Smckusick if (ps.want_blank) /* put a blank before '{' if '{' 749*24453Smckusick * is not at start of line */ 7508800Smckusick *e_code++ = ' '; 751*24453Smckusick ps.want_blank = false; 7528800Smckusick *e_code++ = '{'; 753*24453Smckusick ps.just_saw_decl = 0; 7548800Smckusick break; 7558800Smckusick 756*24453Smckusick case rbrace: /* got a '}' */ 757*24453Smckusick if (ps.p_l_follow) { /* check for unclosed if, for, 758*24453Smckusick * else. */ 759*24453Smckusick diag(1, "Unbalanced parens"); 760*24453Smckusick ps.p_l_follow = 0; 7618800Smckusick sp_sw = false; 7628800Smckusick } 763*24453Smckusick ps.just_saw_decl = 0; 764*24453Smckusick if (s_code != e_code && !ps.block_init) { /* '}' must be first on 765*24453Smckusick * line */ 7668800Smckusick if (verbose) 767*24453Smckusick diag(0, "Line broken"); 768*24453Smckusick dump_line(); 7698800Smckusick } 7708800Smckusick *e_code++ = '}'; 771*24453Smckusick ps.want_blank = true; 772*24453Smckusick ps.in_stmt = ps.ind_stmt = false; 773*24453Smckusick if (ps.dec_nest > 0) { /* we are in multi-level structure 774*24453Smckusick * declaration */ 775*24453Smckusick dec_ind = di_stack[--ps.dec_nest]; 776*24453Smckusick if (ps.dec_nest == 0 && !ps.in_parameter_declaration) 777*24453Smckusick ps.just_saw_decl = 2; 778*24453Smckusick ps.in_decl = true; 7798800Smckusick } 780*24453Smckusick prefix_blankline_requested = 0; 781*24453Smckusick parse(rbrace); /* let parser know about this */ 782*24453Smckusick ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead && ps.il[ps.tos] >= ps.ind_level; 783*24453Smckusick if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0) 784*24453Smckusick postfix_blankline_requested = 1; 7858800Smckusick break; 7868800Smckusick 787*24453Smckusick case swstmt: /* got keyword "switch" */ 7888800Smckusick sp_sw = true; 789*24453Smckusick hd_type = swstmt; /* keep this for when we have seen 790*24453Smckusick * the expression */ 791*24453Smckusick goto copy_id; /* go move the token into buffer */ 7928800Smckusick 793*24453Smckusick case sp_paren: /* token is if, while, for */ 794*24453Smckusick sp_sw = true; /* the interesting stuff is done after the 795*24453Smckusick * expression is scanned */ 7968800Smckusick hd_type = (*token == 'i' ? ifstmt : 797*24453Smckusick (*token == 'w' ? whilestmt : forstmt)); 7988800Smckusick 799*24453Smckusick /* 800*24453Smckusick * remember the type of header for later use by parser 801*24453Smckusick */ 802*24453Smckusick goto copy_id; /* copy the token into line */ 803*24453Smckusick 804*24453Smckusick case sp_nparen: /* got else, do */ 805*24453Smckusick ps.in_stmt = false; 806*24453Smckusick if (*token == 'e') { 807*24453Smckusick if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) { 808*24453Smckusick if (verbose) 809*24453Smckusick diag(0, "Line broken"); 810*24453Smckusick dump_line(); /* make sure this starts a line */ 811*24453Smckusick ps.want_blank = false; 812*24453Smckusick } 813*24453Smckusick force_nl = true; /* also, following stuff must go 814*24453Smckusick * onto new line */ 815*24453Smckusick last_else = 1; 816*24453Smckusick parse(elselit); 817*24453Smckusick } else { 818*24453Smckusick if (e_code != s_code) { /* make sure this starts a 819*24453Smckusick * line */ 820*24453Smckusick if (verbose) 821*24453Smckusick diag(0, "Line broken"); 822*24453Smckusick dump_line(); 823*24453Smckusick ps.want_blank = false; 824*24453Smckusick } 825*24453Smckusick force_nl = true; /* also, following stuff must go 826*24453Smckusick * onto new line */ 827*24453Smckusick last_else = 0; 828*24453Smckusick parse(dolit); 8298800Smckusick } 830*24453Smckusick goto copy_id; /* move the token into line */ 8318800Smckusick 832*24453Smckusick case decl: /* we have a declaration type (int, 833*24453Smckusick * register, etc.) */ 834*24453Smckusick parse(decl); /* let parser worry about indentation */ 835*24453Smckusick if (ps.last_token == rparen && ps.tos <= 1) 836*24453Smckusick ps.in_parameter_declaration = 1; 837*24453Smckusick if (ps.in_parameter_declaration && ps.indent_parameters && ps.dec_nest == 0) { 838*24453Smckusick ps.ind_level = ps.i_l_follow = 1; 839*24453Smckusick ps.ind_stmt = 0; 840*24453Smckusick } 841*24453Smckusick ps.in_or_st = true; /* this might be a structure or 842*24453Smckusick * initialization declaration */ 843*24453Smckusick ps.in_decl = ps.decl_on_line = true; 844*24453Smckusick if ( /* !ps.in_or_st && */ ps.dec_nest <= 0) 845*24453Smckusick ps.just_saw_decl = 2; 846*24453Smckusick prefix_blankline_requested = 0; 847*24453Smckusick for (i = 0; token[i++];); /* get length of token */ 8488800Smckusick 849*24453Smckusick /* 850*24453Smckusick * dec_ind = e_code - s_code + (ps.decl_indent>i ? 851*24453Smckusick * ps.decl_indent : i); 852*24453Smckusick */ 853*24453Smckusick dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i; 8548800Smckusick goto copy_id; 8558800Smckusick 856*24453Smckusick case ident: /* got an identifier or constant */ 857*24453Smckusick if (ps.in_decl) { /* if we are in a declaration, we 858*24453Smckusick * must indent identifier */ 859*24453Smckusick if (ps.want_blank) 8608800Smckusick *e_code++ = ' '; 861*24453Smckusick ps.want_blank = false; 862*24453Smckusick if (is_procname == 0 || !procnames_start_line) { 863*24453Smckusick if (!ps.block_init) 864*24453Smckusick if (troff && !ps.dumped_decl_indent) { 865*24453Smckusick sprintf(e_code, "\\c\n.De %dp+\200p\n", dec_ind * 7); 866*24453Smckusick ps.dumped_decl_indent = 1; 867*24453Smckusick e_code += strlen(e_code); 868*24453Smckusick } else 869*24453Smckusick while ((e_code - s_code) < dec_ind) 870*24453Smckusick *e_code++ = ' '; 871*24453Smckusick } else { 872*24453Smckusick if (dec_ind && s_code != e_code) 873*24453Smckusick dump_line(); 874*24453Smckusick dec_ind = 0; 875*24453Smckusick ps.want_blank = false; 876*24453Smckusick } 877*24453Smckusick } else if (sp_sw && ps.p_l_follow == 0) { 878*24453Smckusick sp_sw = false; 879*24453Smckusick force_nl = true; 880*24453Smckusick ps.last_u_d = true; 881*24453Smckusick ps.in_stmt = false; 882*24453Smckusick parse(hd_type); 8838800Smckusick } 884*24453Smckusick copy_id: 885*24453Smckusick if (ps.want_blank) 8868800Smckusick *e_code++ = ' '; 887*24453Smckusick if (troff && ps.its_a_keyword) { 888*24453Smckusick *e_code++ = BACKSLASH; 889*24453Smckusick *e_code++ = 'f'; 890*24453Smckusick *e_code++ = 'B'; 891*24453Smckusick } 8928800Smckusick for (t_ptr = token; *t_ptr; ++t_ptr) 8938800Smckusick *e_code++ = *t_ptr; 894*24453Smckusick if (troff && ps.its_a_keyword) { 895*24453Smckusick *e_code++ = BACKSLASH; 896*24453Smckusick *e_code++ = 'f'; 897*24453Smckusick *e_code++ = 'R'; 898*24453Smckusick } 899*24453Smckusick ps.want_blank = true; 9008800Smckusick break; 9018800Smckusick 902*24453Smckusick case period: /* treat a period kind of like a binary 903*24453Smckusick * operation */ 904*24453Smckusick *e_code++ = '.';/* move the period into line */ 905*24453Smckusick ps.want_blank = false; /* dont put a blank after a period */ 9068800Smckusick break; 9078800Smckusick 908*24453Smckusick case comma: 909*24453Smckusick ps.want_blank = (s_code != e_code); /* only put blank after 910*24453Smckusick * comma if comma does 911*24453Smckusick * not start the line */ 912*24453Smckusick if (ps.in_decl && is_procname == 0 && !ps.block_init) 9138800Smckusick while ((e_code - s_code) < (dec_ind - 1)) 9148800Smckusick *e_code++ = ' '; 9158800Smckusick 9168800Smckusick *e_code++ = ','; 917*24453Smckusick if (ps.p_l_follow == 0) { 918*24453Smckusick ps.block_init = 0; 919*24453Smckusick if (break_comma && !ps.leave_comma) 920*24453Smckusick force_nl = true; 921*24453Smckusick } 9228800Smckusick break; 9238800Smckusick 924*24453Smckusick case preesc: /* got the character '#' */ 925*24453Smckusick if ((s_com != e_com) || 926*24453Smckusick (s_lab != e_lab) || 927*24453Smckusick (s_code != e_code)) 928*24453Smckusick dump_line(); 929*24453Smckusick *e_lab++ = '#'; /* move whole line to 'label' buffer */ 930*24453Smckusick { 931*24453Smckusick int in_comment = 0; 932*24453Smckusick char *com_start = 0; 933*24453Smckusick char quote = 0; 934*24453Smckusick char *com_end = 0; 9358800Smckusick 936*24453Smckusick while (*buf_ptr != '\n' || in_comment) { 937*24453Smckusick *e_lab = *buf_ptr++; 938*24453Smckusick if (buf_ptr >= buf_end) 939*24453Smckusick fill_buffer(); 940*24453Smckusick switch (*e_lab++) { 941*24453Smckusick case BACKSLASH: 942*24453Smckusick if (troff) 943*24453Smckusick *e_lab++ = BACKSLASH; 944*24453Smckusick if (!in_comment) { 945*24453Smckusick *e_lab++ = *buf_ptr++; 946*24453Smckusick if (buf_ptr >= buf_end) 947*24453Smckusick fill_buffer(); 948*24453Smckusick } 949*24453Smckusick break; 950*24453Smckusick case '/': 951*24453Smckusick if (*buf_ptr == '*' && !in_comment && !quote) { 952*24453Smckusick in_comment = 1; 953*24453Smckusick *e_lab++ = *buf_ptr++; 954*24453Smckusick com_start = e_lab - 2; 955*24453Smckusick } 956*24453Smckusick break; 957*24453Smckusick case '"': 958*24453Smckusick if (quote == '"') 959*24453Smckusick quote = 0; 960*24453Smckusick break; 961*24453Smckusick case '\'': 962*24453Smckusick if (quote == '\'') 963*24453Smckusick quote = 0; 964*24453Smckusick break; 965*24453Smckusick case '*': 966*24453Smckusick if (*buf_ptr == '/' && in_comment) { 967*24453Smckusick in_comment = 0; 968*24453Smckusick *e_lab++ = *buf_ptr++; 969*24453Smckusick com_end = e_lab; 970*24453Smckusick } 971*24453Smckusick break; 972*24453Smckusick } 9738800Smckusick } 974*24453Smckusick while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 975*24453Smckusick e_lab--; 976*24453Smckusick if (e_lab == com_end && bp_save == 0) { /* comment on 977*24453Smckusick * preprocessor line */ 978*24453Smckusick if (sc_end == 0) /* if this is the first 979*24453Smckusick * comment, we must set up 980*24453Smckusick * the buffer */ 981*24453Smckusick sc_end = &(save_com[0]); 982*24453Smckusick else { 983*24453Smckusick *sc_end++ = '\n'; /* add newline between 984*24453Smckusick * comments */ 985*24453Smckusick *sc_end++ = ' '; 986*24453Smckusick --line_no; 987*24453Smckusick } 988*24453Smckusick bcopy(com_start, sc_end, com_end - com_start); 989*24453Smckusick sc_end += com_end - com_start; 990*24453Smckusick e_lab = com_start; 991*24453Smckusick while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 992*24453Smckusick e_lab--; 993*24453Smckusick bp_save = buf_ptr; /* save current input 994*24453Smckusick * buffer */ 995*24453Smckusick be_save = buf_end; 996*24453Smckusick buf_ptr = save_com; /* fix so that subsequent 997*24453Smckusick * calls to lexi will take 998*24453Smckusick * tokens out of save_com */ 999*24453Smckusick *sc_end++ = ' '; /* add trailing blank, 1000*24453Smckusick * just in case */ 1001*24453Smckusick buf_end = sc_end; 1002*24453Smckusick sc_end = 0; 1003*24453Smckusick } 1004*24453Smckusick *e_lab = '\0'; /* null terminate line */ 1005*24453Smckusick ps.pcase = false; 10068800Smckusick } 1007*24453Smckusick if (strncmp(s_lab, "#if", 3) == 0) 1008*24453Smckusick if (ifdef_level < sizeof state_stack / sizeof state_stack[0]) { 1009*24453Smckusick match_state[ifdef_level].tos = -1; 1010*24453Smckusick state_stack[ifdef_level++] = ps; 1011*24453Smckusick } else 1012*24453Smckusick diag(1, "#if stack overflow"); 1013*24453Smckusick else if (strncmp(s_lab, "#else", 5) == 0) 1014*24453Smckusick if (ifdef_level <= 0) 1015*24453Smckusick diag(1, "Unmatched #else"); 1016*24453Smckusick else { 1017*24453Smckusick match_state[ifdef_level - 1] = ps; 1018*24453Smckusick ps = state_stack[ifdef_level - 1]; 1019*24453Smckusick } else if (strncmp(s_lab, "#endif", 6) == 0) 1020*24453Smckusick if (ifdef_level <= 0) 1021*24453Smckusick diag(1, "Unmatched #endif"); 1022*24453Smckusick else { 1023*24453Smckusick ifdef_level--; 1024*24453Smckusick #ifdef undef 10258800Smckusick 1026*24453Smckusick /* 1027*24453Smckusick * This match needs to be more intelligent before 1028*24453Smckusick * the message is useful 1029*24453Smckusick */ 1030*24453Smckusick if (match_state[ifdef_level].tos >= 0 1031*24453Smckusick && bcmp(&ps, &match_state[ifdef_level], sizeof ps)) 1032*24453Smckusick diag(0, "Syntactically inconsistant #ifdef alternatives."); 1033*24453Smckusick #endif 1034*24453Smckusick } 1035*24453Smckusick break; /* subsequent processing of the newline 1036*24453Smckusick * character will cause the line to be 1037*24453Smckusick * printed */ 10388800Smckusick 1039*24453Smckusick case comment: /* we have gotten a /* this is a biggie */ 1040*24453Smckusick proc_comment: 1041*24453Smckusick if (flushed_nl) { /* we should force a broken line 1042*24453Smckusick * here */ 1043*24453Smckusick flushed_nl = false; 1044*24453Smckusick dump_line(); 1045*24453Smckusick ps.want_blank = false; /* dont insert blank at 1046*24453Smckusick * line start */ 1047*24453Smckusick force_nl = false; 1048*24453Smckusick } 1049*24453Smckusick pr_comment(); 10508800Smckusick break; 1051*24453Smckusick } /* end of big switch stmt */ 1052*24453Smckusick *e_code = '\0'; /* make sure code section is null 1053*24453Smckusick * terminated */ 1054*24453Smckusick if (type_code != comment && type_code != newline && type_code != preesc) 1055*24453Smckusick ps.last_token = type_code; 1056*24453Smckusick } /* end of main while (1) loop */ 10578800Smckusick }; 10588800Smckusick 10598800Smckusick /* 1060*24453Smckusick * copy input file to backup file if in_name is /blah/blah/blah/file, then 1061*24453Smckusick * backup file will be ".Bfile" then make the backup file the input and 1062*24453Smckusick * original input file the output 10638800Smckusick */ 1064*24453Smckusick bakcopy() 1065*24453Smckusick { 1066*24453Smckusick int n, 1067*24453Smckusick bakchn; 1068*24453Smckusick char buff[512]; 1069*24453Smckusick register char *p; 10708800Smckusick 1071*24453Smckusick /* construct file name .Bfile */ 1072*24453Smckusick for (p = in_name; *p; p++); /* skip to end of string */ 1073*24453Smckusick while (p > in_name && *p != '/') /* find last '/' */ 10748800Smckusick p--; 10758800Smckusick if (*p == '/') 10768800Smckusick p++; 1077*24453Smckusick sprintf(bakfile, "%s.BAK", p); 10788800Smckusick 1079*24453Smckusick /* copy in_name to backup file */ 1080*24453Smckusick bakchn = creat(bakfile, 0600); 10818800Smckusick if (bakchn < 0) { 1082*24453Smckusick printf("can't create backup file \"%s\"\n", bakfile); 1083*24453Smckusick exit(); 10848800Smckusick } 1085*24453Smckusick while (n = read(fileno(input), buff, 512)) 1086*24453Smckusick write(bakchn, buff, n); 1087*24453Smckusick close(bakchn); 1088*24453Smckusick fclose(input); 10898800Smckusick 1090*24453Smckusick /* re-open backup file as the input file */ 1091*24453Smckusick input = fopen(bakfile, "r"); 10928800Smckusick if (input < 0) { 1093*24453Smckusick printf("can't re-open backup file\n"); 1094*24453Smckusick exit(); 10958800Smckusick } 1096*24453Smckusick /* now the original input file will be the output */ 1097*24453Smckusick output = fopen(in_name, "w"); 1098*24453Smckusick if (output == 0) { 1099*24453Smckusick printf("can't create %s\n", in_name); 1100*24453Smckusick unlink(bakfile); 1101*24453Smckusick exit(); 11028800Smckusick } 11038800Smckusick } 11048800Smckusick 11058800Smckusick 1106*24453Smckusick char *param_start; 1107*24453Smckusick 1108*24453Smckusick eqin(s1, s2) 1109*24453Smckusick register char *s1; 1110*24453Smckusick register char *s2; 11118800Smckusick { 1112*24453Smckusick while (*s1) { 1113*24453Smckusick if (*s1++ != *s2++) 1114*24453Smckusick return (false); 11158800Smckusick } 1116*24453Smckusick param_start = s2; 1117*24453Smckusick return (true); 11188800Smckusick } 11198800Smckusick 11208800Smckusick 1121*24453Smckusick set_option(arg) 1122*24453Smckusick char *arg; 11238800Smckusick { 1124*24453Smckusick if (!eqin("-npro", arg)) 1125*24453Smckusick if (eqin("-lc", arg)) /* comment line length */ 1126*24453Smckusick block_comment_max_col = atoi(param_start); 1127*24453Smckusick else if (eqin("-lp", arg)) 1128*24453Smckusick lineup_to_parens = 1; 1129*24453Smckusick else if (eqin("-nlp", arg)) 1130*24453Smckusick lineup_to_parens = 0; 1131*24453Smckusick else if (eqin("-l", arg)) /* line length */ 1132*24453Smckusick max_col = atoi(param_start); 1133*24453Smckusick else if (eqin("-psl", arg)) /* if true, the names of 1134*24453Smckusick * procedures being defined get 1135*24453Smckusick * placed in column 1 (ie. a 1136*24453Smckusick * newline is placed between the 1137*24453Smckusick * type of the procedure and its 1138*24453Smckusick * name) */ 1139*24453Smckusick procnames_start_line = 1; 1140*24453Smckusick else if (eqin("-npsl", arg)) 1141*24453Smckusick procnames_start_line = 0; 1142*24453Smckusick else if (eqin("-fc1", arg)) 1143*24453Smckusick format_col1_comments = 1; 1144*24453Smckusick else if (eqin("-nfc1", arg)) 1145*24453Smckusick format_col1_comments = 0; 1146*24453Smckusick else if (eqin("-pcs", arg)) /* If true, procedure calls look 1147*24453Smckusick * like: foo(bar) rather than foo 1148*24453Smckusick * (bar) */ 1149*24453Smckusick proc_calls_space = 1; 1150*24453Smckusick else if (eqin("-npcs", arg)) 1151*24453Smckusick proc_calls_space = 0; 1152*24453Smckusick else if (eqin("-ip", arg)) /* indent parameters */ 1153*24453Smckusick ps.indent_parameters = 1; 1154*24453Smckusick else if (eqin("-nip", arg)) /* no indent parameters */ 1155*24453Smckusick ps.indent_parameters = 0; 1156*24453Smckusick else if (eqin("-cli", arg)) { /* case label indent */ 1157*24453Smckusick extern float atof(); 1158*24453Smckusick 1159*24453Smckusick ps.case_indent = atof(param_start); 1160*24453Smckusick } 1161*24453Smckusick else if (eqin("-ci",arg)) 1162*24453Smckusick continuation_indent = atoi(param_start); 1163*24453Smckusick else if (eqin("-cdb", arg)) /* comment delimiters should be on 1164*24453Smckusick * lines by themselves */ 1165*24453Smckusick comment_delimiter_on_blankline = 1; 1166*24453Smckusick else if (eqin("-ncdb", arg)) /* comment delimiters shouldnt be 1167*24453Smckusick * on lines by themselves */ 1168*24453Smckusick comment_delimiter_on_blankline = 0; 1169*24453Smckusick else if (eqin("-i", arg)) /* indent width */ 1170*24453Smckusick ps.ind_size = atoi(param_start); 1171*24453Smckusick else if (eqin("-cd", arg)) /* indent for comments on 1172*24453Smckusick * declarations */ 1173*24453Smckusick ps.decl_com_ind = atoi(param_start); 1174*24453Smckusick else if (eqin("-ce", arg)) /* true iff 'else' should cuddle 1175*24453Smckusick * up to '}' */ 1176*24453Smckusick cuddle_else = 1; 1177*24453Smckusick else if (eqin("-c", arg)) /* comment indent */ 1178*24453Smckusick ps.com_ind = atoi(param_start); 1179*24453Smckusick else if (eqin("-v", arg)) /* spew out rubbish */ 11808800Smckusick verbose = true; 1181*24453Smckusick else if (eqin("-nv", arg)) /* keep quiet */ 11828800Smckusick verbose = false; 1183*24453Smckusick else if (eqin("-dj", arg)) 1184*24453Smckusick ps.ljust_decl = true; 1185*24453Smckusick else if (eqin("-ndj", arg)) 1186*24453Smckusick ps.ljust_decl = false; 1187*24453Smckusick else if (eqin("-nbc", arg)) /* dont break after commas in 1188*24453Smckusick * declarations */ 1189*24453Smckusick ps.leave_comma = true; 1190*24453Smckusick else if (eqin("-bc", arg)) /* break after commas in 1191*24453Smckusick * declarations */ 1192*24453Smckusick ps.leave_comma = false; 1193*24453Smckusick else if (eqin("-di", arg)) /* indent from type to varname in 1194*24453Smckusick * a declaration */ 1195*24453Smckusick ps.decl_indent = atoi(param_start); 1196*24453Smckusick else if (eqin("-d", arg)) 1197*24453Smckusick ps.unindent_displace = atoi(param_start); 1198*24453Smckusick else if (eqin("-br", arg)) 11998800Smckusick btype_2 = true; 1200*24453Smckusick else if (eqin("-bl", arg)) 12018800Smckusick btype_2 = false; 1202*24453Smckusick else if (eqin("-st", arg)) { /* input and output on standard IO */ 1203*24453Smckusick if (input == 0) 1204*24453Smckusick input = stdin; 1205*24453Smckusick if (output == 0) 1206*24453Smckusick output = stdout; 1207*24453Smckusick } else if (eqin("-ei", arg)) /* else-ifs should be stuck 1208*24453Smckusick * together */ 1209*24453Smckusick ps.else_if = 1; 1210*24453Smckusick else if (eqin("-nei", arg)) /* else-ifs should be broken apart */ 1211*24453Smckusick ps.else_if = 0; 1212*24453Smckusick else if (eqin("-nce", arg)) /* else should always start a line */ 1213*24453Smckusick cuddle_else = 0; 1214*24453Smckusick else if (eqin("-sc", arg)) /* comment continuations should 1215*24453Smckusick * start with a * */ 1216*24453Smckusick star_comment_cont = 1; 1217*24453Smckusick else if (eqin("-nsc", arg)) 1218*24453Smckusick star_comment_cont = 0; /* comments shouldnt start with a 1219*24453Smckusick * star */ 1220*24453Smckusick else if (eqin("-bap", arg)) /* blanklines after procedures */ 1221*24453Smckusick blanklines_after_procs = 1; 1222*24453Smckusick else if (eqin("-nbap", arg)) /* blanklines after procedures */ 1223*24453Smckusick blanklines_after_procs = 0; 1224*24453Smckusick else if (eqin("-sob", arg)) /* swallow optional blanklines */ 1225*24453Smckusick swallow_optional_blanklines = 1; 1226*24453Smckusick else if (eqin("-nsob", arg)) /* swallow optional blanklines */ 1227*24453Smckusick swallow_optional_blanklines = 0; 1228*24453Smckusick else if (eqin("-bad", arg)) /* blanklines after declarations */ 1229*24453Smckusick blanklines_after_declarations = 1; 1230*24453Smckusick else if (eqin("-nbad", arg)) /* blanklines after declarations */ 1231*24453Smckusick blanklines_after_declarations = 0; 1232*24453Smckusick else if (eqin("-bbb", arg)) /* blanklines before blockcomments */ 1233*24453Smckusick blanklines_before_blockcomments = 1; 1234*24453Smckusick else if (eqin("-nbbb", arg)) /* blanklines before blockcomments */ 1235*24453Smckusick blanklines_before_blockcomments = 0; 1236*24453Smckusick else if (eqin("-troff", arg)) 1237*24453Smckusick troff = 1; 1238*24453Smckusick else if (arg[0] == '-' && arg[1] == 'T') /* -Ttypename */ 1239*24453Smckusick addkey(arg + 2, 4); 1240*24453Smckusick else { /* illegal arg given */ 1241*24453Smckusick printf("Unknown parameter: %s\n", arg); 1242*24453Smckusick exit(); 1243*24453Smckusick } 12448800Smckusick } 12458800Smckusick 12468800Smckusick 12478800Smckusick /* 1248*24453Smckusick * GETPRO - get profile file profile file is max 127 characters 12498800Smckusick */ 1250*24453Smckusick getpro(name, buf, len) 1251*24453Smckusick char *name, /* profile file name, as in '.indent.pro' */ 1252*24453Smckusick *buf; /* will receive contents of .pro file */ 12538800Smckusick { 12548800Smckusick register chn, 12558800Smckusick n; 1256*24453Smckusick char file[100]; 12578800Smckusick 12588800Smckusick file[0] = 0; 1259*24453Smckusick strcat(file, getenv("HOME")); 1260*24453Smckusick strcat(file, "/"); 1261*24453Smckusick strcat(file, name); 1262*24453Smckusick if ((chn = open(name, 0)) < 0) 1263*24453Smckusick chn = open(file, 0); 12648800Smckusick if (chn < 0) 12658800Smckusick return (-1); 1266*24453Smckusick n = read(chn, buf, len); 12678800Smckusick if (n < 0) 12688800Smckusick return (-1); 1269*24453Smckusick buf[n--] = 0; /* null terminate line */ 12708800Smckusick if (buf[n] == '\n') 12718800Smckusick buf[n] = 0; 1272*24453Smckusick close(chn); 12738800Smckusick return (0); 12748800Smckusick } 12758800Smckusick 12768800Smckusick 12778800Smckusick /* 1278*24453Smckusick * strip off arguments in a string: p is address of a character pointer 1279*24453Smckusick * nextchr returns pointer to front of first arg arg is null terminated. p 1280*24453Smckusick * is reset to after arg for subsequent calls 12818800Smckusick */ 1282*24453Smckusick char * 1283*24453Smckusick nxtarg(p) 1284*24453Smckusick char **p; 12858800Smckusick { 1286*24453Smckusick register char *f, 1287*24453Smckusick *b; 1288*24453Smckusick 1289*24453Smckusick f = *p; 1290*24453Smckusick while (*f && *f <= ' ') 12918800Smckusick f++; 1292*24453Smckusick b = f; 1293*24453Smckusick while (*b > ' ') 12948800Smckusick b++; 12958800Smckusick if (*b != 0) 12968800Smckusick *b++ = 0; 12978800Smckusick *p = b; 12988800Smckusick return (f); 12998800Smckusick } 13008800Smckusick 13018800Smckusick 1302*24453Smckusick set_profile() 1303*24453Smckusick { 1304*24453Smckusick char line[1000], 1305*24453Smckusick *b; 1306*24453Smckusick register char *f; 1307*24453Smckusick extern char *nxtarg(); 13088800Smckusick 1309*24453Smckusick if (getpro(".indent.pro", line, sizeof line) < 0) 13108800Smckusick return; 13118800Smckusick b = line; 1312*24453Smckusick if (verbose) 1313*24453Smckusick printf("profile: %s\n", b); 1314*24453Smckusick while (*(f = nxtarg(&b))) 1315*24453Smckusick set_option(f); 13168800Smckusick } 1317