121968Sdist /* 2*35500Sbostic * Copyright (c) 1985 Sun Microsystems, Inc. 3*35500Sbostic * Copyright (c) 1980 The Regents of the University of California. 433767Sbostic * Copyright (c) 1976 Board of Trustees of the University of Illinois. 533767Sbostic * All rights reserved. 633767Sbostic * 733767Sbostic * Redistribution and use in source and binary forms are permitted 834885Sbostic * provided that the above copyright notice and this paragraph are 934885Sbostic * duplicated in all such forms and that any documentation, 1034885Sbostic * advertising materials, and other materials related to such 1134885Sbostic * distribution and use acknowledge that the software was developed 12*35500Sbostic * by the University of California, Berkeley, the University of Illinois, 13*35500Sbostic * Urbana, and Sun Microsystems, Inc. The name of either University 14*35500Sbostic * or Sun Microsystems may not be used to endorse or promote products 15*35500Sbostic * derived from this software without specific prior written permission. 1634885Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1734885Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1834885Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1921968Sdist */ 208800Smckusick 2121968Sdist #ifndef lint 2221968Sdist char copyright[] = 23*35500Sbostic "@(#) Copyright (c) 1985 Sun Microsystems, Inc.\n\ 24*35500Sbostic @(#) Copyright (c) 1980 The Regents of the University of California.\n\ 25*35500Sbostic @(#) Copyright (c) 1976 Board of Trustees of the University of Illinois.\n\ 2621968Sdist All rights reserved.\n"; 2733767Sbostic #endif /* not lint */ 2821968Sdist 2921968Sdist #ifndef lint 30*35500Sbostic static char sccsid[] = "@(#)indent.c 5.9 (Berkeley) 09/15/88"; 3133767Sbostic #endif /* not lint */ 3221968Sdist 33*35500Sbostic #include "indent_globs.h"; 34*35500Sbostic #include "indent_codes.h"; 35*35500Sbostic #include <sys/param.h> 36*35500Sbostic #include <ctype.h> 378800Smckusick 38*35500Sbostic char *in_name = "Standard Input"; /* will always point to name of input 39*35500Sbostic * file */ 40*35500Sbostic char *out_name = "Standard Output"; /* will always point to name 41*35500Sbostic * of output file */ 42*35500Sbostic char bakfile[MAXPATHLEN] = ""; 438800Smckusick 4424453Smckusick main(argc, argv) 4524453Smckusick int argc; 4624453Smckusick char **argv; 478800Smckusick { 488800Smckusick 4924453Smckusick int dec_ind; /* current indentation for declarations */ 5024453Smckusick int di_stack[20]; /* a stack of structure indentation levels */ 51*35500Sbostic int flushed_nl; /* used when buffering up comments to remember 52*35500Sbostic * that a newline was passed over */ 5324453Smckusick int force_nl; /* when true, code must be broken */ 54*35500Sbostic int hd_type; /* used to store type of stmt for if (...), 55*35500Sbostic * for (...), etc */ 5624453Smckusick register int i; /* local loop counter */ 5724453Smckusick register int j; /* local loop counter */ 58*35500Sbostic int scase; /* set to true when we see a case, so we will 59*35500Sbostic * know what to do with the following colon */ 6024453Smckusick int sp_sw; /* when true, we are in the expressin of 6124453Smckusick * if(...), while(...), etc. */ 6224453Smckusick int squest; /* when this is positive, we have seen a ? 6324453Smckusick * without the matching : in a <c>?<s>:<s> 6424453Smckusick * construct */ 6524453Smckusick register char *t_ptr; /* used for copying tokens */ 6624453Smckusick int type_code; /* the type of token, returned by lexi */ 678800Smckusick 6824453Smckusick int last_else = 0; /* true iff last keyword was an else */ 698800Smckusick 708800Smckusick 7124453Smckusick /*-----------------------------------------------*\ 7224648Smckusick | INITIALIZATION | 7324648Smckusick \*-----------------------------------------------*/ 748800Smckusick 758800Smckusick 7624453Smckusick ps.p_stack[0] = stmt; /* this is the parser's stack */ 77*35500Sbostic ps.last_nl = true; /* this is true if the last thing scanned was 78*35500Sbostic * a newline */ 7924453Smckusick ps.last_token = semicolon; 80*35500Sbostic combuf = (char *) malloc(bufsize); 81*35500Sbostic labbuf = (char *) malloc(bufsize); 82*35500Sbostic codebuf = (char *) malloc(bufsize); 83*35500Sbostic l_com = combuf + bufsize - 5; 84*35500Sbostic l_lab = labbuf + bufsize - 5; 85*35500Sbostic l_code = codebuf + bufsize - 5; 8624453Smckusick combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and 8724453Smckusick * comment buffers */ 888800Smckusick combuf[1] = codebuf[1] = labbuf[1] = '\0'; 89*35500Sbostic ps.else_if = 1; /* Default else-if special processing to on */ 908800Smckusick s_lab = e_lab = labbuf + 1; 918800Smckusick s_code = e_code = codebuf + 1; 928800Smckusick s_com = e_com = combuf + 1; 938800Smckusick 948800Smckusick buf_ptr = buf_end = in_buffer; 958800Smckusick line_no = 1; 9624453Smckusick had_eof = ps.in_decl = ps.decl_on_line = break_comma = false; 978800Smckusick sp_sw = force_nl = false; 9824453Smckusick ps.in_or_st = false; 9924453Smckusick ps.bl_line = true; 1008800Smckusick dec_ind = 0; 10124453Smckusick di_stack[ps.dec_nest = 0] = 0; 10224453Smckusick ps.want_blank = ps.in_stmt = ps.ind_stmt = false; 1038800Smckusick 1048800Smckusick 10524453Smckusick scase = ps.pcase = false; 1068800Smckusick squest = 0; 1078800Smckusick sc_end = 0; 1088800Smckusick bp_save = 0; 1098800Smckusick be_save = 0; 1108800Smckusick 11124453Smckusick output = 0; 1128800Smckusick 1138800Smckusick 1148800Smckusick 11524453Smckusick /*--------------------------------------------------*\ 116*35500Sbostic | COMMAND LINE SCAN | 11724648Smckusick \*--------------------------------------------------*/ 1188800Smckusick 119*35500Sbostic #ifdef undef 120*35500Sbostic max_col = 78; /* -l78 */ 121*35500Sbostic lineup_to_parens = 1; /* -lp */ 122*35500Sbostic ps.ljust_decl = 0; /* -ndj */ 123*35500Sbostic ps.com_ind = 33; /* -c33 */ 124*35500Sbostic star_comment_cont = 1; /* -sc */ 125*35500Sbostic ps.ind_size = 8; /* -i8 */ 126*35500Sbostic verbose = 0; 127*35500Sbostic ps.decl_indent = 16; /* -di16 */ 128*35500Sbostic ps.indent_parameters = 1; /* -ip */ 129*35500Sbostic ps.decl_com_ind = 0; /* if this is not set to some positive value 130*35500Sbostic * by an arg, we will set this equal to 131*35500Sbostic * ps.com_ind */ 132*35500Sbostic btype_2 = 1; /* -br */ 133*35500Sbostic cuddle_else = 1; /* -ce */ 134*35500Sbostic ps.unindent_displace = 0; /* -d0 */ 135*35500Sbostic ps.case_indent = 0; /* -cli0 */ 136*35500Sbostic format_col1_comments = 1; /* -fc1 */ 137*35500Sbostic procnames_start_line = 1; /* -psl */ 138*35500Sbostic proc_calls_space = 0; /* -npcs */ 139*35500Sbostic comment_delimiter_on_blankline = 1; /* -cdb */ 140*35500Sbostic ps.leave_comma = 1; /* -nbc */ 141*35500Sbostic #endif 1428800Smckusick 14324453Smckusick for (i = 1; i < argc; ++i) 14424453Smckusick if (strcmp(argv[i], "-npro") == 0) 14524453Smckusick break; 146*35500Sbostic set_defaults(); 14724453Smckusick if (i >= argc) 14824453Smckusick set_profile(); 1498800Smckusick 1508800Smckusick for (i = 1; i < argc; ++i) { 15124453Smckusick 15224453Smckusick /* 153*35500Sbostic * look thru args (if any) for changes to defaults 15424453Smckusick */ 1558800Smckusick if (argv[i][0] != '-') {/* no flag on parameter */ 15624453Smckusick if (input == 0) { /* we must have the input file */ 15724453Smckusick in_name = argv[i]; /* remember name of input file */ 15824453Smckusick input = fopen(in_name, "r"); 15924453Smckusick if (input == 0) { /* check for open error */ 16024648Smckusick fprintf(stderr, "indent: can't open %s\n", argv[i]); 16124648Smckusick exit(1); 1628800Smckusick } 1638800Smckusick continue; 164*35500Sbostic } 165*35500Sbostic else if (output == 0) { /* we have the output file */ 16624453Smckusick out_name = argv[i]; /* remember name of output file */ 16724453Smckusick if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite 16824453Smckusick * the file */ 16924648Smckusick fprintf(stderr, "indent: input and output files must be different\n"); 17024648Smckusick exit(1); 17124453Smckusick } 17224453Smckusick output = fopen(out_name, "w"); 17324453Smckusick if (output == 0) { /* check for create error */ 17424648Smckusick fprintf(stderr, "indent: can't create %s\n", argv[i]); 17524648Smckusick exit(1); 17624453Smckusick } 17724453Smckusick continue; 1788800Smckusick } 17924648Smckusick fprintf(stderr, "indent: unknown parameter: %s\n", argv[i]); 18024648Smckusick exit(1); 181*35500Sbostic } 182*35500Sbostic else 18324453Smckusick set_option(argv[i]); 18424453Smckusick } /* end of for */ 18524453Smckusick if (input == 0) { 186*35500Sbostic fprintf(stderr, "indent: usage: indent file [ outfile ] [ options ]\n"); 18724648Smckusick exit(1); 18824453Smckusick } 18924453Smckusick if (output == 0) 19024453Smckusick if (troff) 19124453Smckusick output = stdout; 19224453Smckusick else { 19324453Smckusick out_name = in_name; 19424453Smckusick bakcopy(); 1958800Smckusick } 19624453Smckusick if (ps.com_ind <= 1) 197*35500Sbostic ps.com_ind = 2; /* dont put normal comments before column 2 */ 198*35500Sbostic if (troff) { 199*35500Sbostic if (bodyf.font[0] == 0) 200*35500Sbostic parsefont(&bodyf, "R"); 201*35500Sbostic if (scomf.font[0] == 0) 202*35500Sbostic parsefont(&scomf, "I"); 203*35500Sbostic if (blkcomf.font[0] == 0) 204*35500Sbostic blkcomf = scomf, blkcomf.size += 2; 205*35500Sbostic if (boxcomf.font[0] == 0) 206*35500Sbostic boxcomf = blkcomf; 207*35500Sbostic if (stringf.font[0] == 0) 208*35500Sbostic parsefont(&stringf, "L"); 209*35500Sbostic if (keywordf.font[0] == 0) 210*35500Sbostic parsefont(&keywordf, "B"); 211*35500Sbostic writefdef(&bodyf, 'B'); 212*35500Sbostic writefdef(&scomf, 'C'); 213*35500Sbostic writefdef(&blkcomf, 'L'); 214*35500Sbostic writefdef(&boxcomf, 'X'); 215*35500Sbostic writefdef(&stringf, 'S'); 216*35500Sbostic writefdef(&keywordf, 'K'); 217*35500Sbostic } 21824453Smckusick if (block_comment_max_col <= 0) 21924453Smckusick block_comment_max_col = max_col; 22024453Smckusick if (ps.decl_com_ind <= 0) /* if not specified by user, set this */ 221*35500Sbostic ps.decl_com_ind = ps.ljust_decl ? (ps.com_ind <= 10 ? 2 : ps.com_ind - 8) : ps.com_ind; 22224453Smckusick if (continuation_indent == 0) 22324453Smckusick continuation_indent = ps.ind_size; 224*35500Sbostic fill_buffer(); /* get first batch of stuff into input buffer */ 2258800Smckusick 22624453Smckusick parse(semicolon); 22724453Smckusick { 22824453Smckusick register char *p = buf_ptr; 22924453Smckusick register col = 1; 2308800Smckusick 23124453Smckusick while (1) { 23224453Smckusick if (*p == ' ') 23324453Smckusick col++; 23424453Smckusick else if (*p == '\t') 23524453Smckusick col = ((col - 1) & ~7) + 9; 23624453Smckusick else 23724453Smckusick break; 23824453Smckusick p++; 23924453Smckusick }; 24024453Smckusick if (col > ps.ind_size) 24124453Smckusick ps.ind_level = ps.i_l_follow = col / ps.ind_size; 2428800Smckusick } 24324453Smckusick if (troff) { 24424453Smckusick register char *p = in_name, 24524453Smckusick *beg = in_name; 24624453Smckusick 24724453Smckusick while (*p) 24824453Smckusick if (*p++ == '/') 24924453Smckusick beg = p; 25024453Smckusick fprintf(output, ".Fn \"%s\"\n", beg); 2518800Smckusick } 25224453Smckusick /* 253*35500Sbostic * START OF MAIN LOOP 25424453Smckusick */ 2558800Smckusick 256*35500Sbostic while (1) { /* this is the main loop. it will go until we 257*35500Sbostic * reach eof */ 25824453Smckusick int is_procname; 2598800Smckusick 26024453Smckusick type_code = lexi(); /* lexi reads one token. The actual 261*35500Sbostic * characters read are stored in "token". lexi 262*35500Sbostic * returns a code indicating the type of token */ 26324453Smckusick is_procname = ps.procname[0]; 2648800Smckusick 26524453Smckusick /* 266*35500Sbostic * The following code moves everything following an if (), while (), 267*35500Sbostic * else, etc. up to the start of the following stmt to a buffer. This 268*35500Sbostic * allows proper handling of both kinds of brace placement. 26924453Smckusick */ 2708800Smckusick 2718800Smckusick flushed_nl = false; 27224453Smckusick while (ps.search_brace) { /* if we scanned an if(), while(), 273*35500Sbostic * etc., we might need to copy stuff 274*35500Sbostic * into a buffer we must loop, copying 275*35500Sbostic * stuff into save_com, until we find 276*35500Sbostic * the start of the stmt which follows 27724453Smckusick * the if, or whatever */ 2788800Smckusick switch (type_code) { 279*35500Sbostic case newline: 280*35500Sbostic ++line_no; 281*35500Sbostic flushed_nl = true; 282*35500Sbostic case form_feed: 283*35500Sbostic break; /* form feeds and newlines found here will be 284*35500Sbostic * ignored */ 2858800Smckusick 286*35500Sbostic case lbrace: /* this is a brace that starts the compound 287*35500Sbostic * stmt */ 288*35500Sbostic if (sc_end == 0) { /* ignore buffering if a comment wasnt 289*35500Sbostic * stored up */ 290*35500Sbostic ps.search_brace = false; 291*35500Sbostic goto check_type; 292*35500Sbostic } 293*35500Sbostic if (btype_2) { 294*35500Sbostic save_com[0] = '{'; /* we either want to put the brace 295*35500Sbostic * right after the if */ 296*35500Sbostic goto sw_buffer; /* go to common code to get out of 29724453Smckusick * this loop */ 298*35500Sbostic } 299*35500Sbostic case comment: /* we have a comment, so we must copy it into 300*35500Sbostic * the buffer */ 301*35500Sbostic if (!flushed_nl || sc_end != 0) { 302*35500Sbostic if (sc_end == 0) { /* if this is the first comment, we 303*35500Sbostic * must set up the buffer */ 304*35500Sbostic save_com[0] = save_com[1] = ' '; 305*35500Sbostic sc_end = &(save_com[2]); 3068800Smckusick } 307*35500Sbostic else { 308*35500Sbostic *sc_end++ = '\n'; /* add newline between 30924453Smckusick * comments */ 310*35500Sbostic *sc_end++ = ' '; 311*35500Sbostic --line_no; 312*35500Sbostic } 313*35500Sbostic *sc_end++ = '/'; /* copy in start of comment */ 314*35500Sbostic *sc_end++ = '*'; 3158800Smckusick 316*35500Sbostic for (;;) { /* loop until we get to the end of the comment */ 317*35500Sbostic *sc_end = *buf_ptr++; 318*35500Sbostic if (buf_ptr >= buf_end) 319*35500Sbostic fill_buffer(); 32024453Smckusick 321*35500Sbostic if (*sc_end++ == '*' && *buf_ptr == '/') 322*35500Sbostic break; /* we are at end of comment */ 32324453Smckusick 324*35500Sbostic if (sc_end >= &(save_com[sc_size])) { /* check for temp buffer 325*35500Sbostic * overflow */ 326*35500Sbostic diag(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever."); 327*35500Sbostic fflush(output); 328*35500Sbostic exit(1); 32924453Smckusick } 33024453Smckusick } 331*35500Sbostic *sc_end++ = '/'; /* add ending slash */ 332*35500Sbostic if (++buf_ptr >= buf_end) /* get past / in buffer */ 333*35500Sbostic fill_buffer(); 334*35500Sbostic break; 335*35500Sbostic } 336*35500Sbostic default: /* it is the start of a normal statment */ 337*35500Sbostic if (flushed_nl) /* if we flushed a newline, make sure it is 338*35500Sbostic * put back */ 339*35500Sbostic force_nl = true; 340*35500Sbostic if (type_code == sp_paren && *token == 'i' 34124453Smckusick && last_else && ps.else_if 34224453Smckusick || type_code == sp_nparen && *token == 'e' 34324453Smckusick && e_code != s_code && e_code[-1] == '}') 344*35500Sbostic force_nl = false; 3458800Smckusick 346*35500Sbostic if (sc_end == 0) { /* ignore buffering if comment wasnt 347*35500Sbostic * saved up */ 348*35500Sbostic ps.search_brace = false; 349*35500Sbostic goto check_type; 350*35500Sbostic } 351*35500Sbostic if (force_nl) { /* if we should insert a nl here, put it into 352*35500Sbostic * the buffer */ 353*35500Sbostic force_nl = false; 354*35500Sbostic --line_no; /* this will be re-increased when the nl is 355*35500Sbostic * read from the buffer */ 356*35500Sbostic *sc_end++ = '\n'; 357*35500Sbostic *sc_end++ = ' '; 358*35500Sbostic if (verbose && !flushed_nl) /* print error msg if the line 359*35500Sbostic * was not already broken */ 360*35500Sbostic diag(0, "Line broken"); 361*35500Sbostic flushed_nl = false; 362*35500Sbostic } 363*35500Sbostic for (t_ptr = token; *t_ptr; ++t_ptr) 364*35500Sbostic *sc_end++ = *t_ptr; /* copy token into temp buffer */ 365*35500Sbostic ps.procname[0] = 0; 3668800Smckusick 367*35500Sbostic sw_buffer: 368*35500Sbostic ps.search_brace = false; /* stop looking for start of 369*35500Sbostic * stmt */ 370*35500Sbostic bp_save = buf_ptr; /* save current input buffer */ 371*35500Sbostic be_save = buf_end; 372*35500Sbostic buf_ptr = save_com; /* fix so that subsequent calls to 37324453Smckusick * lexi will take tokens out of 37424453Smckusick * save_com */ 375*35500Sbostic *sc_end++ = ' ';/* add trailing blank, just in case */ 376*35500Sbostic buf_end = sc_end; 377*35500Sbostic sc_end = 0; 378*35500Sbostic break; 37924453Smckusick } /* end of switch */ 380*35500Sbostic if (type_code != 0) /* we must make this check, just in case there 381*35500Sbostic * was an unexpected EOF */ 38224453Smckusick type_code = lexi(); /* read another token */ 383*35500Sbostic /* if (ps.search_brace) ps.procname[0] = 0; */ 384*35500Sbostic if ((is_procname = ps.procname[0]) && flushed_nl 385*35500Sbostic && !procnames_start_line && ps.in_decl 386*35500Sbostic && type_code == ident) 387*35500Sbostic flushed_nl = 0; 388*35500Sbostic } /* end of while (search_brace) */ 38924453Smckusick last_else = 0; 39024453Smckusick check_type: 39124453Smckusick if (type_code == 0) { /* we got eof */ 3928800Smckusick if (s_lab != e_lab || s_code != e_code 393*35500Sbostic || s_com != e_com) /* must dump end of line */ 39424453Smckusick dump_line(); 39524453Smckusick if (ps.tos > 1) /* check for balanced braces */ 39624453Smckusick diag(1, "Stuff missing from end of file."); 3978800Smckusick 3988800Smckusick if (verbose) { 39924453Smckusick printf("There were %d output lines and %d comments\n", 40024453Smckusick ps.out_lines, ps.out_coms); 40124453Smckusick printf("(Lines with comments)/(Lines with code): %6.3f\n", 40224453Smckusick (1.0 * ps.com_lines) / code_lines); 4038800Smckusick } 40424453Smckusick fflush(output); 405*35500Sbostic exit(1); 4068800Smckusick } 4078800Smckusick if ( 408*35500Sbostic (type_code != comment) && 409*35500Sbostic (type_code != newline) && 410*35500Sbostic (type_code != preesc) && 411*35500Sbostic (type_code != form_feed)) { 412*35500Sbostic if (force_nl && 413*35500Sbostic (type_code != semicolon) && 414*35500Sbostic (type_code != lbrace || !btype_2)) { 415*35500Sbostic /* we should force a broken line here */ 4168800Smckusick if (verbose && !flushed_nl) 41724453Smckusick diag(0, "Line broken"); 4188800Smckusick flushed_nl = false; 41924453Smckusick dump_line(); 42024453Smckusick ps.want_blank = false; /* dont insert blank at line start */ 4218800Smckusick force_nl = false; 4228800Smckusick } 423*35500Sbostic ps.in_stmt = true; /* turn on flag which causes an extra level of 424*35500Sbostic * indentation. this is turned off by a ; or 425*35500Sbostic * '}' */ 426*35500Sbostic if (s_com != e_com) { /* the turkey has embedded a comment 427*35500Sbostic * in a line. fix it */ 4288800Smckusick *e_code++ = ' '; 429*35500Sbostic for (t_ptr = s_com; *t_ptr; ++t_ptr) { 430*35500Sbostic check_size(code); 4318800Smckusick *e_code++ = *t_ptr; 432*35500Sbostic } 4338800Smckusick *e_code++ = ' '; 43424453Smckusick *e_code = '\0'; /* null terminate code sect */ 43524453Smckusick ps.want_blank = false; 4368800Smckusick e_com = s_com; 4378800Smckusick } 438*35500Sbostic } 439*35500Sbostic else if (type_code != comment) /* preserve force_nl thru a comment */ 440*35500Sbostic force_nl = false; /* cancel forced newline after newline, form 441*35500Sbostic * feed, etc */ 4428800Smckusick 4438800Smckusick 4448800Smckusick 445*35500Sbostic /*-----------------------------------------------------*\ 446*35500Sbostic | do switch on type of token scanned | 447*35500Sbostic \*-----------------------------------------------------*/ 448*35500Sbostic check_size(code); 44924453Smckusick switch (type_code) { /* now, decide what to do with the token */ 45024453Smckusick 451*35500Sbostic case form_feed: /* found a form feed in line */ 452*35500Sbostic ps.use_ff = true; /* a form feed is treated much like a newline */ 453*35500Sbostic dump_line(); 454*35500Sbostic ps.want_blank = false; 455*35500Sbostic break; 456*35500Sbostic 457*35500Sbostic case newline: 458*35500Sbostic if (ps.last_token != comma || ps.p_l_follow > 0 459*35500Sbostic || !ps.leave_comma || ps.block_init || !break_comma || s_com != e_com) { 46024453Smckusick dump_line(); 46124453Smckusick ps.want_blank = false; 462*35500Sbostic } 463*35500Sbostic ++line_no; /* keep track of input line number */ 464*35500Sbostic break; 4658800Smckusick 466*35500Sbostic case lparen: /* got a '(' or '[' */ 467*35500Sbostic ++ps.p_l_follow; /* count parens to make Healy happy */ 468*35500Sbostic if (ps.want_blank && *token != '[' && 469*35500Sbostic (ps.last_token != ident || proc_calls_space 470*35500Sbostic || (ps.its_a_keyword && (!ps.sizeof_keyword || Bill_Shannon)))) 471*35500Sbostic *e_code++ = ' '; 472*35500Sbostic if (ps.in_decl && !ps.block_init) 473*35500Sbostic if (troff && !ps.dumped_decl_indent && !is_procname && ps.last_token == decl) { 474*35500Sbostic ps.dumped_decl_indent = 1; 475*35500Sbostic sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); 476*35500Sbostic e_code += strlen(e_code); 47724453Smckusick } 478*35500Sbostic else { 479*35500Sbostic while ((e_code - s_code) < dec_ind) { 480*35500Sbostic check_size(code); 481*35500Sbostic *e_code++ = ' '; 482*35500Sbostic } 48324453Smckusick *e_code++ = token[0]; 4848800Smckusick } 485*35500Sbostic else 486*35500Sbostic *e_code++ = token[0]; 487*35500Sbostic ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code; 488*35500Sbostic if (sp_sw && ps.p_l_follow == 1 && extra_expression_indent 489*35500Sbostic && ps.paren_indents[0] < 2 * ps.ind_size) 490*35500Sbostic ps.paren_indents[0] = 2 * ps.ind_size; 491*35500Sbostic ps.want_blank = false; 492*35500Sbostic if (ps.in_or_st && *token == '(' && ps.tos <= 2) { 493*35500Sbostic /* 494*35500Sbostic * this is a kluge to make sure that declarations will be 495*35500Sbostic * aligned right if proc decl has an explicit type on it, i.e. 496*35500Sbostic * "int a(x) {..." 497*35500Sbostic */ 498*35500Sbostic parse(semicolon); /* I said this was a kluge... */ 499*35500Sbostic ps.in_or_st = false; /* turn off flag for structure decl or 500*35500Sbostic * initialization */ 501*35500Sbostic } 502*35500Sbostic if (ps.sizeof_keyword) 503*35500Sbostic ps.sizeof_mask |= 1 << ps.p_l_follow; 504*35500Sbostic break; 5058800Smckusick 506*35500Sbostic case rparen: /* got a ')' or ']' */ 507*35500Sbostic if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask) { 508*35500Sbostic ps.last_u_d = true; 509*35500Sbostic ps.cast_mask &= (1 << ps.p_l_follow) - 1; 510*35500Sbostic } 511*35500Sbostic ps.sizeof_mask &= (1 << ps.p_l_follow) - 1; 512*35500Sbostic if (--ps.p_l_follow < 0) { 513*35500Sbostic ps.p_l_follow = 0; 514*35500Sbostic diag(0, "Extra %c", *token); 515*35500Sbostic } 516*35500Sbostic if (e_code == s_code) /* if the paren starts the line */ 517*35500Sbostic ps.paren_level = ps.p_l_follow; /* then indent it */ 5188800Smckusick 519*35500Sbostic *e_code++ = token[0]; 520*35500Sbostic ps.want_blank = true; 5218800Smckusick 522*35500Sbostic if (sp_sw && (ps.p_l_follow == 0)) { /* check for end of if 52324453Smckusick * (...), or some such */ 524*35500Sbostic sp_sw = false; 525*35500Sbostic force_nl = true;/* must force newline after if */ 526*35500Sbostic ps.last_u_d = true; /* inform lexi that a following 52724453Smckusick * operator is unary */ 528*35500Sbostic ps.in_stmt = false; /* dont use stmt continuation 52924453Smckusick * indentation */ 5308800Smckusick 531*35500Sbostic parse(hd_type); /* let parser worry about if, or whatever */ 532*35500Sbostic } 533*35500Sbostic ps.search_brace = btype_2; /* this should insure that constructs 534*35500Sbostic * such as main(){...} and int[]{...} 535*35500Sbostic * have their braces put in the right 536*35500Sbostic * place */ 537*35500Sbostic break; 5388800Smckusick 539*35500Sbostic case unary_op: /* this could be any unary operation */ 540*35500Sbostic if (ps.want_blank) 541*35500Sbostic *e_code++ = ' '; 5428800Smckusick 543*35500Sbostic if (troff && !ps.dumped_decl_indent && ps.in_decl && !is_procname) { 544*35500Sbostic sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); 545*35500Sbostic ps.dumped_decl_indent = 1; 546*35500Sbostic e_code += strlen(e_code); 547*35500Sbostic } 548*35500Sbostic else { 549*35500Sbostic char *res = token; 55024453Smckusick 551*35500Sbostic if (ps.in_decl && !ps.block_init) { /* if this is a unary op 55224453Smckusick * in a declaration, we 55324453Smckusick * should indent this 55424453Smckusick * token */ 555*35500Sbostic for (i = 0; token[i]; ++i); /* find length of token */ 556*35500Sbostic while ((e_code - s_code) < (dec_ind - i)) { 557*35500Sbostic check_size(code); 558*35500Sbostic *e_code++ = ' '; /* pad it */ 55924453Smckusick } 5608800Smckusick } 561*35500Sbostic if (troff && token[0] == '-' && token[1] == '>') 562*35500Sbostic res = "\\(->"; 563*35500Sbostic for (t_ptr = res; *t_ptr; ++t_ptr) { 564*35500Sbostic check_size(code); 565*35500Sbostic *e_code++ = *t_ptr; 566*35500Sbostic } 567*35500Sbostic } 568*35500Sbostic ps.want_blank = false; 569*35500Sbostic break; 5708800Smckusick 571*35500Sbostic case binary_op: /* any binary operation */ 572*35500Sbostic do_binary: 573*35500Sbostic if (ps.want_blank) 574*35500Sbostic *e_code++ = ' '; 575*35500Sbostic { 576*35500Sbostic char *res = token; 57724453Smckusick 578*35500Sbostic if (troff) 579*35500Sbostic switch (token[0]) { 580*35500Sbostic case '<': 581*35500Sbostic if (token[1] == '=') 582*35500Sbostic res = "\\(<="; 583*35500Sbostic break; 584*35500Sbostic case '>': 585*35500Sbostic if (token[1] == '=') 586*35500Sbostic res = "\\(>="; 587*35500Sbostic break; 588*35500Sbostic case '!': 589*35500Sbostic if (token[1] == '=') 590*35500Sbostic res = "\\(!="; 591*35500Sbostic break; 592*35500Sbostic case '|': 593*35500Sbostic if (token[1] == '|') 594*35500Sbostic res = "\\(br\\(br"; 595*35500Sbostic else if (token[1] == 0) 596*35500Sbostic res = "\\(br"; 597*35500Sbostic break; 598*35500Sbostic } 599*35500Sbostic for (t_ptr = res; *t_ptr; ++t_ptr) { 600*35500Sbostic check_size(code); 601*35500Sbostic *e_code++ = *t_ptr; /* move the operator */ 60224453Smckusick } 603*35500Sbostic } 604*35500Sbostic ps.want_blank = true; 605*35500Sbostic break; 6068800Smckusick 607*35500Sbostic case postop: /* got a trailing ++ or -- */ 608*35500Sbostic *e_code++ = token[0]; 609*35500Sbostic *e_code++ = token[1]; 610*35500Sbostic ps.want_blank = true; 611*35500Sbostic break; 6128800Smckusick 613*35500Sbostic case question: /* got a ? */ 614*35500Sbostic squest++; /* this will be used when a later colon 61524453Smckusick * appears so we can distinguish the 61624453Smckusick * <c>?<n>:<n> construct */ 617*35500Sbostic if (ps.want_blank) 618*35500Sbostic *e_code++ = ' '; 619*35500Sbostic *e_code++ = '?'; 620*35500Sbostic ps.want_blank = true; 621*35500Sbostic break; 622*35500Sbostic 623*35500Sbostic case casestmt: /* got word 'case' or 'default' */ 624*35500Sbostic scase = true; /* so we can process the later colon properly */ 625*35500Sbostic goto copy_id; 626*35500Sbostic 627*35500Sbostic case colon: /* got a ':' */ 628*35500Sbostic if (squest > 0) { /* it is part of the <c>?<n>: <n> construct */ 629*35500Sbostic --squest; 63024453Smckusick if (ps.want_blank) 6318800Smckusick *e_code++ = ' '; 632*35500Sbostic *e_code++ = ':'; 63324453Smckusick ps.want_blank = true; 6348800Smckusick break; 635*35500Sbostic } 636*35500Sbostic if (ps.in_decl) { 637*35500Sbostic *e_code++ = ':'; 63824453Smckusick ps.want_blank = false; 6398800Smckusick break; 640*35500Sbostic } 641*35500Sbostic ps.in_stmt = false; /* seeing a label does not imply we are in a 642*35500Sbostic * stmt */ 643*35500Sbostic for (t_ptr = s_code; *t_ptr; ++t_ptr) 644*35500Sbostic *e_lab++ = *t_ptr; /* turn everything so far into a label */ 645*35500Sbostic e_code = s_code; 646*35500Sbostic *e_lab++ = ':'; 647*35500Sbostic *e_lab++ = ' '; 648*35500Sbostic *e_lab = '\0'; 6498800Smckusick 650*35500Sbostic force_nl = ps.pcase = scase; /* ps.pcase will be used by 651*35500Sbostic * dump_line to decide how to 652*35500Sbostic * indent the label. force_nl 653*35500Sbostic * will force a case n: to be 654*35500Sbostic * on a line by itself */ 655*35500Sbostic scase = false; 656*35500Sbostic ps.want_blank = false; 657*35500Sbostic break; 6588800Smckusick 659*35500Sbostic case semicolon: /* got a ';' */ 660*35500Sbostic ps.in_or_st = false;/* we are not in an initialization or 661*35500Sbostic * structure declaration */ 662*35500Sbostic scase = false; /* these will only need resetting in a error */ 663*35500Sbostic squest = 0; 664*35500Sbostic if (ps.last_token == rparen) 665*35500Sbostic ps.in_parameter_declaration = 0; 666*35500Sbostic ps.cast_mask = 0; 667*35500Sbostic ps.sizeof_mask = 0; 668*35500Sbostic ps.block_init = 0; 669*35500Sbostic ps.block_init_level = 0; 670*35500Sbostic ps.just_saw_decl--; 6718800Smckusick 672*35500Sbostic if (ps.in_decl && s_code == e_code && !ps.block_init) 673*35500Sbostic while ((e_code - s_code) < (dec_ind - 1)) { 674*35500Sbostic check_size(code); 675*35500Sbostic *e_code++ = ' '; 676*35500Sbostic } 6778800Smckusick 678*35500Sbostic ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level 679*35500Sbostic * structure declaration, we 680*35500Sbostic * arent any more */ 68124453Smckusick 682*35500Sbostic if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) { 6838800Smckusick 684*35500Sbostic /* 685*35500Sbostic * This should be true iff there were unbalanced parens in the 686*35500Sbostic * stmt. It is a bit complicated, because the semicolon might 687*35500Sbostic * be in a for stmt 688*35500Sbostic */ 689*35500Sbostic diag(1, "Unbalanced parens"); 690*35500Sbostic ps.p_l_follow = 0; 691*35500Sbostic if (sp_sw) { /* this is a check for a if, while, etc. with 692*35500Sbostic * unbalanced parens */ 693*35500Sbostic sp_sw = false; 694*35500Sbostic parse(hd_type); /* dont lose the if, or whatever */ 6958800Smckusick } 696*35500Sbostic } 697*35500Sbostic *e_code++ = ';'; 698*35500Sbostic ps.want_blank = true; 699*35500Sbostic ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the 700*35500Sbostic * middle of a stmt */ 7018800Smckusick 702*35500Sbostic if (!sp_sw) { /* if not if for (;;) */ 703*35500Sbostic parse(semicolon); /* let parser know about end of stmt */ 704*35500Sbostic force_nl = true;/* force newline after a end of stmt */ 705*35500Sbostic } 706*35500Sbostic break; 7078800Smckusick 708*35500Sbostic case lbrace: /* got a '{' */ 709*35500Sbostic ps.in_stmt = false; /* dont indent the {} */ 710*35500Sbostic if (!ps.block_init) 711*35500Sbostic force_nl = true;/* force other stuff on same line as '{' onto 712*35500Sbostic * new line */ 713*35500Sbostic else if (ps.block_init_level <= 0) 714*35500Sbostic ps.block_init_level = 1; 715*35500Sbostic else 716*35500Sbostic ps.block_init_level++; 7178800Smckusick 718*35500Sbostic if (s_code != e_code && !ps.block_init) { 719*35500Sbostic if (!btype_2) { 720*35500Sbostic dump_line(); 721*35500Sbostic ps.want_blank = false; 7228800Smckusick } 723*35500Sbostic else if (ps.in_parameter_declaration && !ps.in_or_st) { 724*35500Sbostic ps.i_l_follow = 0; 725*35500Sbostic dump_line(); 726*35500Sbostic ps.want_blank = false; 7278800Smckusick } 728*35500Sbostic } 729*35500Sbostic if (ps.in_parameter_declaration) 730*35500Sbostic prefix_blankline_requested = 0; 7318800Smckusick 732*35500Sbostic if (ps.p_l_follow > 0) { /* check for preceeding unbalanced 733*35500Sbostic * parens */ 734*35500Sbostic diag(1, "Unbalanced parens"); 735*35500Sbostic ps.p_l_follow = 0; 736*35500Sbostic if (sp_sw) { /* check for unclosed if, for, etc. */ 7378800Smckusick sp_sw = false; 738*35500Sbostic parse(hd_type); 739*35500Sbostic ps.ind_level = ps.i_l_follow; 7408800Smckusick } 741*35500Sbostic } 742*35500Sbostic if (s_code == e_code) 743*35500Sbostic ps.ind_stmt = false; /* dont put extra indentation on line 744*35500Sbostic * with '{' */ 745*35500Sbostic if (ps.in_decl && ps.in_or_st) { /* this is either a structure 746*35500Sbostic * declaration or an init */ 747*35500Sbostic di_stack[ps.dec_nest++] = dec_ind; 748*35500Sbostic /* ? dec_ind = 0; */ 749*35500Sbostic } 750*35500Sbostic else { 751*35500Sbostic ps.decl_on_line = false; /* we cant be in the middle of 752*35500Sbostic * a declaration, so dont do 753*35500Sbostic * special indentation of 754*35500Sbostic * comments */ 755*35500Sbostic if (blanklines_after_declarations_at_proctop 756*35500Sbostic && ps.in_parameter_declaration) 75724453Smckusick postfix_blankline_requested = 1; 758*35500Sbostic ps.in_parameter_declaration = 0; 759*35500Sbostic } 760*35500Sbostic dec_ind = 0; 761*35500Sbostic parse(lbrace); /* let parser know about this */ 762*35500Sbostic if (ps.want_blank) /* put a blank before '{' if '{' is not at 763*35500Sbostic * start of line */ 764*35500Sbostic *e_code++ = ' '; 765*35500Sbostic ps.want_blank = false; 766*35500Sbostic *e_code++ = '{'; 767*35500Sbostic ps.just_saw_decl = 0; 768*35500Sbostic break; 7698800Smckusick 770*35500Sbostic case rbrace: /* got a '}' */ 771*35500Sbostic if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be 772*35500Sbostic * omitted in 773*35500Sbostic * declarations */ 774*35500Sbostic parse(semicolon); 775*35500Sbostic if (ps.p_l_follow) {/* check for unclosed if, for, else. */ 776*35500Sbostic diag(1, "Unbalanced parens"); 777*35500Sbostic ps.p_l_follow = 0; 778*35500Sbostic sp_sw = false; 779*35500Sbostic } 780*35500Sbostic ps.just_saw_decl = 0; 781*35500Sbostic ps.block_init_level--; 782*35500Sbostic if (s_code != e_code && !ps.block_init) { /* '}' must be first on 783*35500Sbostic * line */ 784*35500Sbostic if (verbose) 785*35500Sbostic diag(0, "Line broken"); 786*35500Sbostic dump_line(); 787*35500Sbostic } 788*35500Sbostic *e_code++ = '}'; 789*35500Sbostic ps.want_blank = true; 790*35500Sbostic ps.in_stmt = ps.ind_stmt = false; 791*35500Sbostic if (ps.dec_nest > 0) { /* we are in multi-level structure 792*35500Sbostic * declaration */ 793*35500Sbostic dec_ind = di_stack[--ps.dec_nest]; 794*35500Sbostic if (ps.dec_nest == 0 && !ps.in_parameter_declaration) 795*35500Sbostic ps.just_saw_decl = 2; 796*35500Sbostic ps.in_decl = true; 797*35500Sbostic } 798*35500Sbostic prefix_blankline_requested = 0; 799*35500Sbostic parse(rbrace); /* let parser know about this */ 800*35500Sbostic ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead 801*35500Sbostic && ps.il[ps.tos] >= ps.ind_level; 802*35500Sbostic if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0) 803*35500Sbostic postfix_blankline_requested = 1; 804*35500Sbostic break; 8058800Smckusick 806*35500Sbostic case swstmt: /* got keyword "switch" */ 807*35500Sbostic sp_sw = true; 808*35500Sbostic hd_type = swstmt; /* keep this for when we have seen the 809*35500Sbostic * expression */ 810*35500Sbostic goto copy_id; /* go move the token into buffer */ 811*35500Sbostic 812*35500Sbostic case sp_paren: /* token is if, while, for */ 813*35500Sbostic sp_sw = true; /* the interesting stuff is done after the 81424453Smckusick * expression is scanned */ 815*35500Sbostic hd_type = (*token == 'i' ? ifstmt : 816*35500Sbostic (*token == 'w' ? whilestmt : forstmt)); 8178800Smckusick 818*35500Sbostic /* 819*35500Sbostic * remember the type of header for later use by parser 820*35500Sbostic */ 821*35500Sbostic goto copy_id; /* copy the token into line */ 82224453Smckusick 823*35500Sbostic case sp_nparen: /* got else, do */ 824*35500Sbostic ps.in_stmt = false; 825*35500Sbostic if (*token == 'e') { 826*35500Sbostic if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) { 827*35500Sbostic if (verbose) 828*35500Sbostic diag(0, "Line broken"); 829*35500Sbostic dump_line();/* make sure this starts a line */ 830*35500Sbostic ps.want_blank = false; 8318800Smckusick } 832*35500Sbostic force_nl = true;/* also, following stuff must go onto new line */ 833*35500Sbostic last_else = 1; 834*35500Sbostic parse(elselit); 835*35500Sbostic } 836*35500Sbostic else { 837*35500Sbostic if (e_code != s_code) { /* make sure this starts a line */ 838*35500Sbostic if (verbose) 839*35500Sbostic diag(0, "Line broken"); 840*35500Sbostic dump_line(); 841*35500Sbostic ps.want_blank = false; 842*35500Sbostic } 843*35500Sbostic force_nl = true;/* also, following stuff must go onto new line */ 844*35500Sbostic last_else = 0; 845*35500Sbostic parse(dolit); 846*35500Sbostic } 847*35500Sbostic goto copy_id; /* move the token into line */ 8488800Smckusick 849*35500Sbostic case decl: /* we have a declaration type (int, register, 850*35500Sbostic * etc.) */ 851*35500Sbostic parse(decl); /* let parser worry about indentation */ 852*35500Sbostic if (ps.last_token == rparen && ps.tos <= 1) { 853*35500Sbostic ps.in_parameter_declaration = 1; 854*35500Sbostic if (s_code != e_code) { 855*35500Sbostic dump_line(); 856*35500Sbostic ps.want_blank = 0; 85724453Smckusick } 858*35500Sbostic } 859*35500Sbostic if (ps.in_parameter_declaration && ps.indent_parameters && ps.dec_nest == 0) { 860*35500Sbostic ps.ind_level = ps.i_l_follow = 1; 861*35500Sbostic ps.ind_stmt = 0; 862*35500Sbostic } 863*35500Sbostic ps.in_or_st = true; /* this might be a structure or initialization 864*35500Sbostic * declaration */ 865*35500Sbostic ps.in_decl = ps.decl_on_line = true; 866*35500Sbostic if ( /* !ps.in_or_st && */ ps.dec_nest <= 0) 867*35500Sbostic ps.just_saw_decl = 2; 868*35500Sbostic prefix_blankline_requested = 0; 869*35500Sbostic for (i = 0; token[i++];); /* get length of token */ 8708800Smckusick 871*35500Sbostic /* 872*35500Sbostic * dec_ind = e_code - s_code + (ps.decl_indent>i ? ps.decl_indent 873*35500Sbostic * : i); 874*35500Sbostic */ 875*35500Sbostic dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i; 876*35500Sbostic goto copy_id; 8778800Smckusick 878*35500Sbostic case ident: /* got an identifier or constant */ 879*35500Sbostic if (ps.in_decl) { /* if we are in a declaration, we must indent 880*35500Sbostic * identifier */ 88124453Smckusick if (ps.want_blank) 8828800Smckusick *e_code++ = ' '; 883*35500Sbostic ps.want_blank = false; 884*35500Sbostic if (is_procname == 0 || !procnames_start_line) { 885*35500Sbostic if (!ps.block_init) 886*35500Sbostic if (troff && !ps.dumped_decl_indent) { 887*35500Sbostic sprintf(e_code, "\n.De %dp+\200p\n", dec_ind * 7); 888*35500Sbostic ps.dumped_decl_indent = 1; 889*35500Sbostic e_code += strlen(e_code); 890*35500Sbostic } 891*35500Sbostic else 892*35500Sbostic while ((e_code - s_code) < dec_ind) { 893*35500Sbostic check_size(code); 894*35500Sbostic *e_code++ = ' '; 895*35500Sbostic } 89624453Smckusick } 897*35500Sbostic else { 898*35500Sbostic if (dec_ind && s_code != e_code) 899*35500Sbostic dump_line(); 900*35500Sbostic dec_ind = 0; 901*35500Sbostic ps.want_blank = false; 902*35500Sbostic } 903*35500Sbostic } 904*35500Sbostic else if (sp_sw && ps.p_l_follow == 0) { 905*35500Sbostic sp_sw = false; 906*35500Sbostic force_nl = true; 907*35500Sbostic ps.last_u_d = true; 908*35500Sbostic ps.in_stmt = false; 909*35500Sbostic parse(hd_type); 910*35500Sbostic } 911*35500Sbostic copy_id: 912*35500Sbostic if (ps.want_blank) 913*35500Sbostic *e_code++ = ' '; 914*35500Sbostic if (troff && ps.its_a_keyword) { 915*35500Sbostic e_code = chfont(&bodyf, &keywordf, e_code); 916*35500Sbostic for (t_ptr = token; *t_ptr; ++t_ptr) { 917*35500Sbostic check_size(code); 918*35500Sbostic *e_code++ = keywordf.allcaps && islower(*t_ptr) 919*35500Sbostic ? toupper(*t_ptr) : *t_ptr; 920*35500Sbostic } 921*35500Sbostic e_code = chfont(&keywordf, &bodyf, e_code); 922*35500Sbostic } 923*35500Sbostic else 924*35500Sbostic for (t_ptr = token; *t_ptr; ++t_ptr) { 925*35500Sbostic check_size(code); 9268800Smckusick *e_code++ = *t_ptr; 92724453Smckusick } 928*35500Sbostic ps.want_blank = true; 929*35500Sbostic break; 9308800Smckusick 931*35500Sbostic case period: /* treat a period kind of like a binary 93224453Smckusick * operation */ 933*35500Sbostic *e_code++ = '.'; /* move the period into line */ 934*35500Sbostic ps.want_blank = false; /* dont put a blank after a period */ 935*35500Sbostic break; 9368800Smckusick 937*35500Sbostic case comma: 938*35500Sbostic ps.want_blank = (s_code != e_code); /* only put blank after comma 939*35500Sbostic * if comma does not start the 940*35500Sbostic * line */ 941*35500Sbostic if (ps.in_decl && is_procname == 0 && !ps.block_init) 942*35500Sbostic while ((e_code - s_code) < (dec_ind - 1)) { 943*35500Sbostic check_size(code); 944*35500Sbostic *e_code++ = ' '; 945*35500Sbostic } 9468800Smckusick 947*35500Sbostic *e_code++ = ','; 948*35500Sbostic if (ps.p_l_follow == 0) { 949*35500Sbostic if (ps.block_init_level <= 0) 95024453Smckusick ps.block_init = 0; 951*35500Sbostic if (break_comma && !ps.leave_comma) 952*35500Sbostic force_nl = true; 953*35500Sbostic } 954*35500Sbostic break; 9558800Smckusick 956*35500Sbostic case preesc: /* got the character '#' */ 957*35500Sbostic if ((s_com != e_com) || 95824453Smckusick (s_lab != e_lab) || 95924453Smckusick (s_code != e_code)) 960*35500Sbostic dump_line(); 961*35500Sbostic *e_lab++ = '#'; /* move whole line to 'label' buffer */ 962*35500Sbostic { 963*35500Sbostic int in_comment = 0; 964*35500Sbostic int com_start = 0; 965*35500Sbostic char quote = 0; 966*35500Sbostic int com_end = 0; 9678800Smckusick 968*35500Sbostic while (*buf_ptr != '\n' || in_comment) { 969*35500Sbostic check_size(lab); 970*35500Sbostic *e_lab = *buf_ptr++; 971*35500Sbostic if (buf_ptr >= buf_end) 972*35500Sbostic fill_buffer(); 973*35500Sbostic switch (*e_lab++) { 974*35500Sbostic case BACKSLASH: 975*35500Sbostic if (troff) 976*35500Sbostic *e_lab++ = BACKSLASH; 977*35500Sbostic if (!in_comment) { 978*35500Sbostic *e_lab++ = *buf_ptr++; 979*35500Sbostic if (buf_ptr >= buf_end) 980*35500Sbostic fill_buffer(); 98124453Smckusick } 982*35500Sbostic break; 983*35500Sbostic case '/': 984*35500Sbostic if (*buf_ptr == '*' && !in_comment && !quote) { 985*35500Sbostic in_comment = 1; 986*35500Sbostic *e_lab++ = *buf_ptr++; 987*35500Sbostic com_start = e_lab - s_lab - 2; 988*35500Sbostic } 989*35500Sbostic break; 990*35500Sbostic case '"': 991*35500Sbostic if (quote == '"') 992*35500Sbostic quote = 0; 993*35500Sbostic break; 994*35500Sbostic case '\'': 995*35500Sbostic if (quote == '\'') 996*35500Sbostic quote = 0; 997*35500Sbostic break; 998*35500Sbostic case '*': 999*35500Sbostic if (*buf_ptr == '/' && in_comment) { 1000*35500Sbostic in_comment = 0; 1001*35500Sbostic *e_lab++ = *buf_ptr++; 1002*35500Sbostic com_end = e_lab - s_lab; 1003*35500Sbostic } 1004*35500Sbostic break; 10058800Smckusick } 1006*35500Sbostic } 1007*35500Sbostic 1008*35500Sbostic while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 1009*35500Sbostic e_lab--; 1010*35500Sbostic if (e_lab - s_lab == com_end && bp_save == 0) { /* comment on 101124453Smckusick * preprocessor line */ 1012*35500Sbostic if (sc_end == 0) /* if this is the first comment, we 1013*35500Sbostic * must set up the buffer */ 1014*35500Sbostic sc_end = &(save_com[0]); 1015*35500Sbostic else { 1016*35500Sbostic *sc_end++ = '\n'; /* add newline between 101724453Smckusick * comments */ 1018*35500Sbostic *sc_end++ = ' '; 1019*35500Sbostic --line_no; 102024453Smckusick } 1021*35500Sbostic bcopy(s_lab + com_start, sc_end, com_end - com_start); 1022*35500Sbostic sc_end += com_end - com_start; 1023*35500Sbostic if (sc_end >= &save_com[sc_size]) 1024*35500Sbostic abort(); 1025*35500Sbostic e_lab = s_lab + com_start; 1026*35500Sbostic while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 1027*35500Sbostic e_lab--; 1028*35500Sbostic bp_save = buf_ptr; /* save current input buffer */ 1029*35500Sbostic be_save = buf_end; 1030*35500Sbostic buf_ptr = save_com; /* fix so that subsequent calls to 1031*35500Sbostic * lexi will take tokens out of 1032*35500Sbostic * save_com */ 1033*35500Sbostic *sc_end++ = ' '; /* add trailing blank, just in case */ 1034*35500Sbostic buf_end = sc_end; 1035*35500Sbostic sc_end = 0; 10368800Smckusick } 1037*35500Sbostic *e_lab = '\0'; /* null terminate line */ 1038*35500Sbostic ps.pcase = false; 1039*35500Sbostic } 1040*35500Sbostic 1041*35500Sbostic if (strncmp(s_lab, "#if", 3) == 0) { 1042*35500Sbostic if (blanklines_around_conditional_compilation) { 1043*35500Sbostic register c; 1044*35500Sbostic prefix_blankline_requested++; 1045*35500Sbostic while ((c = getc(input)) == '\n'); 1046*35500Sbostic ungetc(c, input); 1047*35500Sbostic } 1048*35500Sbostic if (ifdef_level < sizeof state_stack / sizeof state_stack[0]) { 1049*35500Sbostic match_state[ifdef_level].tos = -1; 1050*35500Sbostic state_stack[ifdef_level++] = ps; 1051*35500Sbostic } 1052*35500Sbostic else 1053*35500Sbostic diag(1, "#if stack overflow"); 1054*35500Sbostic } 1055*35500Sbostic else if (strncmp(s_lab, "#else", 5) == 0) 1056*35500Sbostic if (ifdef_level <= 0) 1057*35500Sbostic diag(1, "Unmatched #else"); 1058*35500Sbostic else { 1059*35500Sbostic match_state[ifdef_level - 1] = ps; 1060*35500Sbostic ps = state_stack[ifdef_level - 1]; 1061*35500Sbostic } 1062*35500Sbostic else if (strncmp(s_lab, "#endif", 6) == 0) { 1063*35500Sbostic if (ifdef_level <= 0) 1064*35500Sbostic diag(1, "Unmatched #endif"); 1065*35500Sbostic else { 1066*35500Sbostic ifdef_level--; 1067*35500Sbostic 106824453Smckusick #ifdef undef 1069*35500Sbostic /* 1070*35500Sbostic * This match needs to be more intelligent before the 1071*35500Sbostic * message is useful 1072*35500Sbostic */ 1073*35500Sbostic if (match_state[ifdef_level].tos >= 0 1074*35500Sbostic && bcmp(&ps, &match_state[ifdef_level], sizeof ps)) 1075*35500Sbostic diag(0, "Syntactically inconsistant #ifdef alternatives."); 107624453Smckusick #endif 1077*35500Sbostic } 1078*35500Sbostic if (blanklines_around_conditional_compilation) { 1079*35500Sbostic postfix_blankline_requested++; 1080*35500Sbostic n_real_blanklines = 0; 1081*35500Sbostic } 1082*35500Sbostic } 1083*35500Sbostic break; /* subsequent processing of the newline 1084*35500Sbostic * character will cause the line to be printed */ 10858800Smckusick 1086*35500Sbostic case comment: /* we have gotten a /* this is a biggie */ 1087*35500Sbostic proc_comment: 1088*35500Sbostic if (flushed_nl) { /* we should force a broken line here */ 1089*35500Sbostic flushed_nl = false; 1090*35500Sbostic dump_line(); 1091*35500Sbostic ps.want_blank = false; /* dont insert blank at line start */ 1092*35500Sbostic force_nl = false; 1093*35500Sbostic } 1094*35500Sbostic pr_comment(); 1095*35500Sbostic break; 109624453Smckusick } /* end of big switch stmt */ 1097*35500Sbostic 1098*35500Sbostic *e_code = '\0'; /* make sure code section is null terminated */ 109924453Smckusick if (type_code != comment && type_code != newline && type_code != preesc) 110024453Smckusick ps.last_token = type_code; 110124453Smckusick } /* end of main while (1) loop */ 11028800Smckusick }; 11038800Smckusick 11048800Smckusick /* 1105*35500Sbostic * copy input file to backup file if in_name is /blah/blah/blah/file, then 1106*35500Sbostic * backup file will be ".Bfile" then make the backup file the input and 1107*35500Sbostic * original input file the output 11088800Smckusick */ 110924453Smckusick bakcopy() 111024453Smckusick { 111124453Smckusick int n, 111224453Smckusick bakchn; 1113*35500Sbostic char buff[8 * 1024]; 111424453Smckusick register char *p; 11158800Smckusick 1116*35500Sbostic /* construct file name .Bfile */ 1117*35500Sbostic for (p = in_name; *p; p++); /* skip to end of string */ 1118*35500Sbostic while (p > in_name && *p != '/') /* find last '/' */ 1119*35500Sbostic p--; 1120*35500Sbostic if (*p == '/') 11218800Smckusick p++; 112224453Smckusick sprintf(bakfile, "%s.BAK", p); 11238800Smckusick 112424453Smckusick /* copy in_name to backup file */ 112524453Smckusick bakchn = creat(bakfile, 0600); 11268800Smckusick if (bakchn < 0) { 112724648Smckusick fprintf(stderr, "indent: can't create backup file \"%s\"\n", bakfile); 112824648Smckusick exit(1); 11298800Smckusick } 1130*35500Sbostic while (n = read(fileno(input), buff, sizeof buff)) 113124648Smckusick if (write(bakchn, buff, n) != n) { 113224648Smckusick fprintf(stderr, "indent: error writing backup file \"%s\"\n", 1133*35500Sbostic bakfile); 113424648Smckusick exit(1); 113524648Smckusick } 113624648Smckusick if (n < 0) { 113724648Smckusick fprintf(stderr, "indent: error reading input file \"%s\"\n", in_name); 113824648Smckusick exit(1); 113924648Smckusick } 114024453Smckusick close(bakchn); 114124453Smckusick fclose(input); 11428800Smckusick 114324453Smckusick /* re-open backup file as the input file */ 114424453Smckusick input = fopen(bakfile, "r"); 1145*35500Sbostic if (input == 0) { 114624648Smckusick fprintf(stderr, "indent: can't re-open backup file\n"); 114724648Smckusick exit(1); 11488800Smckusick } 114924453Smckusick /* now the original input file will be the output */ 115024453Smckusick output = fopen(in_name, "w"); 1151*35500Sbostic if (output == 0) { 115224648Smckusick fprintf(stderr, "indent: can't create %s\n", in_name); 115324453Smckusick unlink(bakfile); 115424648Smckusick exit(1); 11558800Smckusick } 11568800Smckusick } 1157