121968Sdist /* 235500Sbostic * Copyright (c) 1985 Sun Microsystems, Inc. 335500Sbostic * Copyright (c) 1980 The Regents of the University of California. 433767Sbostic * Copyright (c) 1976 Board of Trustees of the University of Illinois. 533767Sbostic * All rights reserved. 633767Sbostic * 7*42686Sbostic * %sccs.include.redist.c% 821968Sdist */ 98800Smckusick 1021968Sdist #ifndef lint 1121968Sdist char copyright[] = 1235500Sbostic "@(#) Copyright (c) 1985 Sun Microsystems, Inc.\n\ 1335500Sbostic @(#) Copyright (c) 1980 The Regents of the University of California.\n\ 1435500Sbostic @(#) Copyright (c) 1976 Board of Trustees of the University of Illinois.\n\ 1521968Sdist All rights reserved.\n"; 1633767Sbostic #endif /* not lint */ 1721968Sdist 1821968Sdist #ifndef lint 19*42686Sbostic static char sccsid[] = "@(#)indent.c 5.15 (Berkeley) 06/01/90"; 2033767Sbostic #endif /* not lint */ 2121968Sdist 2236970Sbostic #include <sys/param.h> 2335505Sbostic #include "indent_globs.h" 2435505Sbostic #include "indent_codes.h" 2535500Sbostic #include <ctype.h> 268800Smckusick 2735500Sbostic char *in_name = "Standard Input"; /* will always point to name of input 2835500Sbostic * file */ 2935500Sbostic char *out_name = "Standard Output"; /* will always point to name 3035500Sbostic * of output file */ 3135500Sbostic char bakfile[MAXPATHLEN] = ""; 328800Smckusick 3324453Smckusick main(argc, argv) 3424453Smckusick int argc; 3524453Smckusick char **argv; 368800Smckusick { 378800Smckusick 3835505Sbostic extern int found_err; /* flag set in diag() on error */ 3924453Smckusick int dec_ind; /* current indentation for declarations */ 4024453Smckusick int di_stack[20]; /* a stack of structure indentation levels */ 4135500Sbostic int flushed_nl; /* used when buffering up comments to remember 4235500Sbostic * that a newline was passed over */ 4324453Smckusick int force_nl; /* when true, code must be broken */ 4435500Sbostic int hd_type; /* used to store type of stmt for if (...), 4535500Sbostic * for (...), etc */ 4624453Smckusick register int i; /* local loop counter */ 4735500Sbostic int scase; /* set to true when we see a case, so we will 4835500Sbostic * know what to do with the following colon */ 4924453Smckusick int sp_sw; /* when true, we are in the expressin of 5024453Smckusick * if(...), while(...), etc. */ 5124453Smckusick int squest; /* when this is positive, we have seen a ? 5224453Smckusick * without the matching : in a <c>?<s>:<s> 5324453Smckusick * construct */ 5424453Smckusick register char *t_ptr; /* used for copying tokens */ 5524453Smckusick int type_code; /* the type of token, returned by lexi */ 568800Smckusick 5724453Smckusick int last_else = 0; /* true iff last keyword was an else */ 588800Smckusick 598800Smckusick 6024453Smckusick /*-----------------------------------------------*\ 6124648Smckusick | INITIALIZATION | 6224648Smckusick \*-----------------------------------------------*/ 638800Smckusick 648800Smckusick 6524453Smckusick ps.p_stack[0] = stmt; /* this is the parser's stack */ 6635500Sbostic ps.last_nl = true; /* this is true if the last thing scanned was 6735500Sbostic * a newline */ 6824453Smckusick ps.last_token = semicolon; 6935500Sbostic combuf = (char *) malloc(bufsize); 7035500Sbostic labbuf = (char *) malloc(bufsize); 7135500Sbostic codebuf = (char *) malloc(bufsize); 7238011Sbostic tokenbuf = (char *) malloc(bufsize); 7335500Sbostic l_com = combuf + bufsize - 5; 7435500Sbostic l_lab = labbuf + bufsize - 5; 7535500Sbostic l_code = codebuf + bufsize - 5; 7638011Sbostic l_token = tokenbuf + bufsize - 5; 7724453Smckusick combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and 7824453Smckusick * comment buffers */ 798800Smckusick combuf[1] = codebuf[1] = labbuf[1] = '\0'; 8035500Sbostic ps.else_if = 1; /* Default else-if special processing to on */ 818800Smckusick s_lab = e_lab = labbuf + 1; 828800Smckusick s_code = e_code = codebuf + 1; 838800Smckusick s_com = e_com = combuf + 1; 8438011Sbostic s_token = e_token = tokenbuf + 1; 858800Smckusick 8638011Sbostic in_buffer = (char *) malloc(10); 8738011Sbostic in_buffer_limit = in_buffer + 8; 888800Smckusick buf_ptr = buf_end = in_buffer; 898800Smckusick line_no = 1; 9024453Smckusick had_eof = ps.in_decl = ps.decl_on_line = break_comma = false; 918800Smckusick sp_sw = force_nl = false; 9224453Smckusick ps.in_or_st = false; 9324453Smckusick ps.bl_line = true; 948800Smckusick dec_ind = 0; 9524453Smckusick di_stack[ps.dec_nest = 0] = 0; 9624453Smckusick ps.want_blank = ps.in_stmt = ps.ind_stmt = false; 978800Smckusick 988800Smckusick 9924453Smckusick scase = ps.pcase = false; 1008800Smckusick squest = 0; 1018800Smckusick sc_end = 0; 1028800Smckusick bp_save = 0; 1038800Smckusick be_save = 0; 1048800Smckusick 10524453Smckusick output = 0; 1068800Smckusick 1078800Smckusick 1088800Smckusick 10924453Smckusick /*--------------------------------------------------*\ 11035500Sbostic | COMMAND LINE SCAN | 11124648Smckusick \*--------------------------------------------------*/ 1128800Smckusick 11335500Sbostic #ifdef undef 11435500Sbostic max_col = 78; /* -l78 */ 11535500Sbostic lineup_to_parens = 1; /* -lp */ 11635500Sbostic ps.ljust_decl = 0; /* -ndj */ 11735500Sbostic ps.com_ind = 33; /* -c33 */ 11835500Sbostic star_comment_cont = 1; /* -sc */ 11935500Sbostic ps.ind_size = 8; /* -i8 */ 12035500Sbostic verbose = 0; 12135500Sbostic ps.decl_indent = 16; /* -di16 */ 12235500Sbostic ps.indent_parameters = 1; /* -ip */ 12335500Sbostic ps.decl_com_ind = 0; /* if this is not set to some positive value 12435500Sbostic * by an arg, we will set this equal to 12535500Sbostic * ps.com_ind */ 12635500Sbostic btype_2 = 1; /* -br */ 12735500Sbostic cuddle_else = 1; /* -ce */ 12835500Sbostic ps.unindent_displace = 0; /* -d0 */ 12935500Sbostic ps.case_indent = 0; /* -cli0 */ 13035500Sbostic format_col1_comments = 1; /* -fc1 */ 13135500Sbostic procnames_start_line = 1; /* -psl */ 13235500Sbostic proc_calls_space = 0; /* -npcs */ 13335500Sbostic comment_delimiter_on_blankline = 1; /* -cdb */ 13435500Sbostic ps.leave_comma = 1; /* -nbc */ 13535500Sbostic #endif 1368800Smckusick 13724453Smckusick for (i = 1; i < argc; ++i) 13824453Smckusick if (strcmp(argv[i], "-npro") == 0) 13924453Smckusick break; 14035500Sbostic set_defaults(); 14124453Smckusick if (i >= argc) 14224453Smckusick set_profile(); 1438800Smckusick 1448800Smckusick for (i = 1; i < argc; ++i) { 14524453Smckusick 14624453Smckusick /* 14735500Sbostic * look thru args (if any) for changes to defaults 14824453Smckusick */ 1498800Smckusick if (argv[i][0] != '-') {/* no flag on parameter */ 15024453Smckusick if (input == 0) { /* we must have the input file */ 15124453Smckusick in_name = argv[i]; /* remember name of input file */ 15224453Smckusick input = fopen(in_name, "r"); 15336970Sbostic if (input == 0) /* check for open error */ 15436970Sbostic err(in_name); 1558800Smckusick continue; 15635500Sbostic } 15735500Sbostic else if (output == 0) { /* we have the output file */ 15824453Smckusick out_name = argv[i]; /* remember name of output file */ 15924453Smckusick if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite 16024453Smckusick * the file */ 16124648Smckusick fprintf(stderr, "indent: input and output files must be different\n"); 16224648Smckusick exit(1); 16324453Smckusick } 16424453Smckusick output = fopen(out_name, "w"); 16536970Sbostic if (output == 0) /* check for create error */ 16636970Sbostic err(out_name); 16724453Smckusick continue; 1688800Smckusick } 16924648Smckusick fprintf(stderr, "indent: unknown parameter: %s\n", argv[i]); 17024648Smckusick exit(1); 17135500Sbostic } 17235500Sbostic else 17324453Smckusick set_option(argv[i]); 17424453Smckusick } /* end of for */ 17524453Smckusick if (input == 0) { 17635500Sbostic fprintf(stderr, "indent: usage: indent file [ outfile ] [ options ]\n"); 17724648Smckusick exit(1); 17824453Smckusick } 17924453Smckusick if (output == 0) 18024453Smckusick if (troff) 18124453Smckusick output = stdout; 18224453Smckusick else { 18324453Smckusick out_name = in_name; 18424453Smckusick bakcopy(); 1858800Smckusick } 18624453Smckusick if (ps.com_ind <= 1) 18735500Sbostic ps.com_ind = 2; /* dont put normal comments before column 2 */ 18835500Sbostic if (troff) { 18935500Sbostic if (bodyf.font[0] == 0) 19035500Sbostic parsefont(&bodyf, "R"); 19135500Sbostic if (scomf.font[0] == 0) 19235500Sbostic parsefont(&scomf, "I"); 19335500Sbostic if (blkcomf.font[0] == 0) 19435500Sbostic blkcomf = scomf, blkcomf.size += 2; 19535500Sbostic if (boxcomf.font[0] == 0) 19635500Sbostic boxcomf = blkcomf; 19735500Sbostic if (stringf.font[0] == 0) 19835500Sbostic parsefont(&stringf, "L"); 19935500Sbostic if (keywordf.font[0] == 0) 20035500Sbostic parsefont(&keywordf, "B"); 20135500Sbostic writefdef(&bodyf, 'B'); 20235500Sbostic writefdef(&scomf, 'C'); 20335500Sbostic writefdef(&blkcomf, 'L'); 20435500Sbostic writefdef(&boxcomf, 'X'); 20535500Sbostic writefdef(&stringf, 'S'); 20635500Sbostic writefdef(&keywordf, 'K'); 20735500Sbostic } 20824453Smckusick if (block_comment_max_col <= 0) 20924453Smckusick block_comment_max_col = max_col; 21024453Smckusick if (ps.decl_com_ind <= 0) /* if not specified by user, set this */ 21135500Sbostic ps.decl_com_ind = ps.ljust_decl ? (ps.com_ind <= 10 ? 2 : ps.com_ind - 8) : ps.com_ind; 21224453Smckusick if (continuation_indent == 0) 21324453Smckusick continuation_indent = ps.ind_size; 21435500Sbostic fill_buffer(); /* get first batch of stuff into input buffer */ 2158800Smckusick 21624453Smckusick parse(semicolon); 21724453Smckusick { 21824453Smckusick register char *p = buf_ptr; 21924453Smckusick register col = 1; 2208800Smckusick 22124453Smckusick while (1) { 22224453Smckusick if (*p == ' ') 22324453Smckusick col++; 22424453Smckusick else if (*p == '\t') 22524453Smckusick col = ((col - 1) & ~7) + 9; 22624453Smckusick else 22724453Smckusick break; 22824453Smckusick p++; 22936970Sbostic } 23024453Smckusick if (col > ps.ind_size) 23124453Smckusick ps.ind_level = ps.i_l_follow = col / ps.ind_size; 2328800Smckusick } 23324453Smckusick if (troff) { 23424453Smckusick register char *p = in_name, 23524453Smckusick *beg = in_name; 23624453Smckusick 23724453Smckusick while (*p) 23824453Smckusick if (*p++ == '/') 23924453Smckusick beg = p; 24024453Smckusick fprintf(output, ".Fn \"%s\"\n", beg); 2418800Smckusick } 24224453Smckusick /* 24335500Sbostic * START OF MAIN LOOP 24424453Smckusick */ 2458800Smckusick 24635500Sbostic while (1) { /* this is the main loop. it will go until we 24735500Sbostic * reach eof */ 24824453Smckusick int is_procname; 2498800Smckusick 25024453Smckusick type_code = lexi(); /* lexi reads one token. The actual 25135500Sbostic * characters read are stored in "token". lexi 25235500Sbostic * returns a code indicating the type of token */ 25324453Smckusick is_procname = ps.procname[0]; 2548800Smckusick 25524453Smckusick /* 25635500Sbostic * The following code moves everything following an if (), while (), 25735500Sbostic * else, etc. up to the start of the following stmt to a buffer. This 25835500Sbostic * allows proper handling of both kinds of brace placement. 25924453Smckusick */ 2608800Smckusick 2618800Smckusick flushed_nl = false; 26224453Smckusick while (ps.search_brace) { /* if we scanned an if(), while(), 26335500Sbostic * etc., we might need to copy stuff 26435500Sbostic * into a buffer we must loop, copying 26535500Sbostic * stuff into save_com, until we find 26635500Sbostic * the start of the stmt which follows 26724453Smckusick * the if, or whatever */ 2688800Smckusick switch (type_code) { 26935500Sbostic case newline: 27035500Sbostic ++line_no; 27135500Sbostic flushed_nl = true; 27235500Sbostic case form_feed: 27335500Sbostic break; /* form feeds and newlines found here will be 27435500Sbostic * ignored */ 2758800Smckusick 27635500Sbostic case lbrace: /* this is a brace that starts the compound 27735500Sbostic * stmt */ 27835500Sbostic if (sc_end == 0) { /* ignore buffering if a comment wasnt 27935500Sbostic * stored up */ 28035500Sbostic ps.search_brace = false; 28135500Sbostic goto check_type; 28235500Sbostic } 28335500Sbostic if (btype_2) { 28435500Sbostic save_com[0] = '{'; /* we either want to put the brace 28535500Sbostic * right after the if */ 28635500Sbostic goto sw_buffer; /* go to common code to get out of 28724453Smckusick * this loop */ 28835500Sbostic } 28935500Sbostic case comment: /* we have a comment, so we must copy it into 29035500Sbostic * the buffer */ 29135500Sbostic if (!flushed_nl || sc_end != 0) { 29235500Sbostic if (sc_end == 0) { /* if this is the first comment, we 29335500Sbostic * must set up the buffer */ 29435500Sbostic save_com[0] = save_com[1] = ' '; 29535500Sbostic sc_end = &(save_com[2]); 2968800Smckusick } 29735500Sbostic else { 29835500Sbostic *sc_end++ = '\n'; /* add newline between 29924453Smckusick * comments */ 30035500Sbostic *sc_end++ = ' '; 30135500Sbostic --line_no; 30235500Sbostic } 30335500Sbostic *sc_end++ = '/'; /* copy in start of comment */ 30435500Sbostic *sc_end++ = '*'; 3058800Smckusick 30635500Sbostic for (;;) { /* loop until we get to the end of the comment */ 30735500Sbostic *sc_end = *buf_ptr++; 30835500Sbostic if (buf_ptr >= buf_end) 30935500Sbostic fill_buffer(); 31024453Smckusick 31135500Sbostic if (*sc_end++ == '*' && *buf_ptr == '/') 31235500Sbostic break; /* we are at end of comment */ 31324453Smckusick 31435500Sbostic if (sc_end >= &(save_com[sc_size])) { /* check for temp buffer 31535500Sbostic * overflow */ 31635500Sbostic diag(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever."); 31735500Sbostic fflush(output); 31835500Sbostic exit(1); 31924453Smckusick } 32024453Smckusick } 32135500Sbostic *sc_end++ = '/'; /* add ending slash */ 32235500Sbostic if (++buf_ptr >= buf_end) /* get past / in buffer */ 32335500Sbostic fill_buffer(); 32435500Sbostic break; 32535500Sbostic } 32635500Sbostic default: /* it is the start of a normal statment */ 32735500Sbostic if (flushed_nl) /* if we flushed a newline, make sure it is 32835500Sbostic * put back */ 32935500Sbostic force_nl = true; 33035500Sbostic if (type_code == sp_paren && *token == 'i' 33124453Smckusick && last_else && ps.else_if 33224453Smckusick || type_code == sp_nparen && *token == 'e' 33324453Smckusick && e_code != s_code && e_code[-1] == '}') 33435500Sbostic force_nl = false; 3358800Smckusick 33635500Sbostic if (sc_end == 0) { /* ignore buffering if comment wasnt 33735500Sbostic * saved up */ 33835500Sbostic ps.search_brace = false; 33935500Sbostic goto check_type; 34035500Sbostic } 34135500Sbostic if (force_nl) { /* if we should insert a nl here, put it into 34235500Sbostic * the buffer */ 34335500Sbostic force_nl = false; 34435500Sbostic --line_no; /* this will be re-increased when the nl is 34535500Sbostic * read from the buffer */ 34635500Sbostic *sc_end++ = '\n'; 34735500Sbostic *sc_end++ = ' '; 34835500Sbostic if (verbose && !flushed_nl) /* print error msg if the line 34935500Sbostic * was not already broken */ 35035500Sbostic diag(0, "Line broken"); 35135500Sbostic flushed_nl = false; 35235500Sbostic } 35335500Sbostic for (t_ptr = token; *t_ptr; ++t_ptr) 35435500Sbostic *sc_end++ = *t_ptr; /* copy token into temp buffer */ 35535500Sbostic ps.procname[0] = 0; 3568800Smckusick 35735500Sbostic sw_buffer: 35835500Sbostic ps.search_brace = false; /* stop looking for start of 35935500Sbostic * stmt */ 36035500Sbostic bp_save = buf_ptr; /* save current input buffer */ 36135500Sbostic be_save = buf_end; 36235500Sbostic buf_ptr = save_com; /* fix so that subsequent calls to 36324453Smckusick * lexi will take tokens out of 36424453Smckusick * save_com */ 36535500Sbostic *sc_end++ = ' ';/* add trailing blank, just in case */ 36635500Sbostic buf_end = sc_end; 36735500Sbostic sc_end = 0; 36835500Sbostic break; 36924453Smckusick } /* end of switch */ 37035500Sbostic if (type_code != 0) /* we must make this check, just in case there 37135500Sbostic * was an unexpected EOF */ 37224453Smckusick type_code = lexi(); /* read another token */ 37335500Sbostic /* if (ps.search_brace) ps.procname[0] = 0; */ 37435500Sbostic if ((is_procname = ps.procname[0]) && flushed_nl 37535500Sbostic && !procnames_start_line && ps.in_decl 37635500Sbostic && type_code == ident) 37735500Sbostic flushed_nl = 0; 37835500Sbostic } /* end of while (search_brace) */ 37924453Smckusick last_else = 0; 38024453Smckusick check_type: 38124453Smckusick if (type_code == 0) { /* we got eof */ 3828800Smckusick if (s_lab != e_lab || s_code != e_code 38335500Sbostic || s_com != e_com) /* must dump end of line */ 38424453Smckusick dump_line(); 38524453Smckusick if (ps.tos > 1) /* check for balanced braces */ 38624453Smckusick diag(1, "Stuff missing from end of file."); 3878800Smckusick 3888800Smckusick if (verbose) { 38924453Smckusick printf("There were %d output lines and %d comments\n", 39024453Smckusick ps.out_lines, ps.out_coms); 39124453Smckusick printf("(Lines with comments)/(Lines with code): %6.3f\n", 39224453Smckusick (1.0 * ps.com_lines) / code_lines); 3938800Smckusick } 39424453Smckusick fflush(output); 39535505Sbostic exit(found_err); 3968800Smckusick } 3978800Smckusick if ( 39835500Sbostic (type_code != comment) && 39935500Sbostic (type_code != newline) && 40035500Sbostic (type_code != preesc) && 40135500Sbostic (type_code != form_feed)) { 40235500Sbostic if (force_nl && 40335500Sbostic (type_code != semicolon) && 40435500Sbostic (type_code != lbrace || !btype_2)) { 40535500Sbostic /* we should force a broken line here */ 4068800Smckusick if (verbose && !flushed_nl) 40724453Smckusick diag(0, "Line broken"); 4088800Smckusick flushed_nl = false; 40924453Smckusick dump_line(); 41024453Smckusick ps.want_blank = false; /* dont insert blank at line start */ 4118800Smckusick force_nl = false; 4128800Smckusick } 41335500Sbostic ps.in_stmt = true; /* turn on flag which causes an extra level of 41435500Sbostic * indentation. this is turned off by a ; or 41535500Sbostic * '}' */ 41635500Sbostic if (s_com != e_com) { /* the turkey has embedded a comment 41735500Sbostic * in a line. fix it */ 4188800Smckusick *e_code++ = ' '; 41935500Sbostic for (t_ptr = s_com; *t_ptr; ++t_ptr) { 42040275Sbostic CHECK_SIZE_CODE; 4218800Smckusick *e_code++ = *t_ptr; 42235500Sbostic } 4238800Smckusick *e_code++ = ' '; 42424453Smckusick *e_code = '\0'; /* null terminate code sect */ 42524453Smckusick ps.want_blank = false; 4268800Smckusick e_com = s_com; 4278800Smckusick } 42835500Sbostic } 42935500Sbostic else if (type_code != comment) /* preserve force_nl thru a comment */ 43035500Sbostic force_nl = false; /* cancel forced newline after newline, form 43135500Sbostic * feed, etc */ 4328800Smckusick 4338800Smckusick 4348800Smckusick 43535500Sbostic /*-----------------------------------------------------*\ 43635500Sbostic | do switch on type of token scanned | 43735500Sbostic \*-----------------------------------------------------*/ 43840275Sbostic CHECK_SIZE_CODE; 43924453Smckusick switch (type_code) { /* now, decide what to do with the token */ 44024453Smckusick 44135500Sbostic case form_feed: /* found a form feed in line */ 44235500Sbostic ps.use_ff = true; /* a form feed is treated much like a newline */ 44335500Sbostic dump_line(); 44435500Sbostic ps.want_blank = false; 44535500Sbostic break; 44635500Sbostic 44735500Sbostic case newline: 44835500Sbostic if (ps.last_token != comma || ps.p_l_follow > 0 44935500Sbostic || !ps.leave_comma || ps.block_init || !break_comma || s_com != e_com) { 45024453Smckusick dump_line(); 45124453Smckusick ps.want_blank = false; 45235500Sbostic } 45335500Sbostic ++line_no; /* keep track of input line number */ 45435500Sbostic break; 4558800Smckusick 45635500Sbostic case lparen: /* got a '(' or '[' */ 45735500Sbostic ++ps.p_l_follow; /* count parens to make Healy happy */ 45835500Sbostic if (ps.want_blank && *token != '[' && 45935500Sbostic (ps.last_token != ident || proc_calls_space 46035500Sbostic || (ps.its_a_keyword && (!ps.sizeof_keyword || Bill_Shannon)))) 46135500Sbostic *e_code++ = ' '; 46235500Sbostic if (ps.in_decl && !ps.block_init) 46335500Sbostic if (troff && !ps.dumped_decl_indent && !is_procname && ps.last_token == decl) { 46435500Sbostic ps.dumped_decl_indent = 1; 46535500Sbostic sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); 46635500Sbostic e_code += strlen(e_code); 46724453Smckusick } 46835500Sbostic else { 46935500Sbostic while ((e_code - s_code) < dec_ind) { 47040275Sbostic CHECK_SIZE_CODE; 47135500Sbostic *e_code++ = ' '; 47235500Sbostic } 47324453Smckusick *e_code++ = token[0]; 4748800Smckusick } 47535500Sbostic else 47635500Sbostic *e_code++ = token[0]; 47735500Sbostic ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code; 47835500Sbostic if (sp_sw && ps.p_l_follow == 1 && extra_expression_indent 47935500Sbostic && ps.paren_indents[0] < 2 * ps.ind_size) 48035500Sbostic ps.paren_indents[0] = 2 * ps.ind_size; 48135500Sbostic ps.want_blank = false; 48235500Sbostic if (ps.in_or_st && *token == '(' && ps.tos <= 2) { 48335500Sbostic /* 48435500Sbostic * this is a kluge to make sure that declarations will be 48535500Sbostic * aligned right if proc decl has an explicit type on it, i.e. 48635500Sbostic * "int a(x) {..." 48735500Sbostic */ 48835500Sbostic parse(semicolon); /* I said this was a kluge... */ 48935500Sbostic ps.in_or_st = false; /* turn off flag for structure decl or 49035500Sbostic * initialization */ 49135500Sbostic } 49235500Sbostic if (ps.sizeof_keyword) 49335500Sbostic ps.sizeof_mask |= 1 << ps.p_l_follow; 49435500Sbostic break; 4958800Smckusick 49635500Sbostic case rparen: /* got a ')' or ']' */ 49738011Sbostic rparen_count--; 49835500Sbostic if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask) { 49935500Sbostic ps.last_u_d = true; 50035500Sbostic ps.cast_mask &= (1 << ps.p_l_follow) - 1; 50135500Sbostic } 50235500Sbostic ps.sizeof_mask &= (1 << ps.p_l_follow) - 1; 50335500Sbostic if (--ps.p_l_follow < 0) { 50435500Sbostic ps.p_l_follow = 0; 50535500Sbostic diag(0, "Extra %c", *token); 50635500Sbostic } 50735500Sbostic if (e_code == s_code) /* if the paren starts the line */ 50835500Sbostic ps.paren_level = ps.p_l_follow; /* then indent it */ 5098800Smckusick 51035500Sbostic *e_code++ = token[0]; 51135500Sbostic ps.want_blank = true; 5128800Smckusick 51335500Sbostic if (sp_sw && (ps.p_l_follow == 0)) { /* check for end of if 51424453Smckusick * (...), or some such */ 51535500Sbostic sp_sw = false; 51635500Sbostic force_nl = true;/* must force newline after if */ 51735500Sbostic ps.last_u_d = true; /* inform lexi that a following 51824453Smckusick * operator is unary */ 51935500Sbostic ps.in_stmt = false; /* dont use stmt continuation 52024453Smckusick * indentation */ 5218800Smckusick 52235500Sbostic parse(hd_type); /* let parser worry about if, or whatever */ 52335500Sbostic } 52435500Sbostic ps.search_brace = btype_2; /* this should insure that constructs 52535500Sbostic * such as main(){...} and int[]{...} 52635500Sbostic * have their braces put in the right 52735500Sbostic * place */ 52835500Sbostic break; 5298800Smckusick 53035500Sbostic case unary_op: /* this could be any unary operation */ 53135500Sbostic if (ps.want_blank) 53235500Sbostic *e_code++ = ' '; 5338800Smckusick 53435500Sbostic if (troff && !ps.dumped_decl_indent && ps.in_decl && !is_procname) { 53535500Sbostic sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); 53635500Sbostic ps.dumped_decl_indent = 1; 53735500Sbostic e_code += strlen(e_code); 53835500Sbostic } 53935500Sbostic else { 54035500Sbostic char *res = token; 54124453Smckusick 54235500Sbostic if (ps.in_decl && !ps.block_init) { /* if this is a unary op 54324453Smckusick * in a declaration, we 54424453Smckusick * should indent this 54524453Smckusick * token */ 54635500Sbostic for (i = 0; token[i]; ++i); /* find length of token */ 54735500Sbostic while ((e_code - s_code) < (dec_ind - i)) { 54840275Sbostic CHECK_SIZE_CODE; 54935500Sbostic *e_code++ = ' '; /* pad it */ 55024453Smckusick } 5518800Smckusick } 55235500Sbostic if (troff && token[0] == '-' && token[1] == '>') 55335500Sbostic res = "\\(->"; 55435500Sbostic for (t_ptr = res; *t_ptr; ++t_ptr) { 55540275Sbostic CHECK_SIZE_CODE; 55635500Sbostic *e_code++ = *t_ptr; 55735500Sbostic } 55835500Sbostic } 55935500Sbostic ps.want_blank = false; 56035500Sbostic break; 5618800Smckusick 56235500Sbostic case binary_op: /* any binary operation */ 56335500Sbostic if (ps.want_blank) 56435500Sbostic *e_code++ = ' '; 56535500Sbostic { 56635500Sbostic char *res = token; 56724453Smckusick 56835500Sbostic if (troff) 56935500Sbostic switch (token[0]) { 57035500Sbostic case '<': 57135500Sbostic if (token[1] == '=') 57235500Sbostic res = "\\(<="; 57335500Sbostic break; 57435500Sbostic case '>': 57535500Sbostic if (token[1] == '=') 57635500Sbostic res = "\\(>="; 57735500Sbostic break; 57835500Sbostic case '!': 57935500Sbostic if (token[1] == '=') 58035500Sbostic res = "\\(!="; 58135500Sbostic break; 58235500Sbostic case '|': 58335500Sbostic if (token[1] == '|') 58435500Sbostic res = "\\(br\\(br"; 58535500Sbostic else if (token[1] == 0) 58635500Sbostic res = "\\(br"; 58735500Sbostic break; 58835500Sbostic } 58935500Sbostic for (t_ptr = res; *t_ptr; ++t_ptr) { 59040275Sbostic CHECK_SIZE_CODE; 59135500Sbostic *e_code++ = *t_ptr; /* move the operator */ 59224453Smckusick } 59335500Sbostic } 59435500Sbostic ps.want_blank = true; 59535500Sbostic break; 5968800Smckusick 59735500Sbostic case postop: /* got a trailing ++ or -- */ 59835500Sbostic *e_code++ = token[0]; 59935500Sbostic *e_code++ = token[1]; 60035500Sbostic ps.want_blank = true; 60135500Sbostic break; 6028800Smckusick 60335500Sbostic case question: /* got a ? */ 60435500Sbostic squest++; /* this will be used when a later colon 60524453Smckusick * appears so we can distinguish the 60624453Smckusick * <c>?<n>:<n> construct */ 60735500Sbostic if (ps.want_blank) 60835500Sbostic *e_code++ = ' '; 60935500Sbostic *e_code++ = '?'; 61035500Sbostic ps.want_blank = true; 61135500Sbostic break; 61235500Sbostic 61335500Sbostic case casestmt: /* got word 'case' or 'default' */ 61435500Sbostic scase = true; /* so we can process the later colon properly */ 61535500Sbostic goto copy_id; 61635500Sbostic 61735500Sbostic case colon: /* got a ':' */ 61835500Sbostic if (squest > 0) { /* it is part of the <c>?<n>: <n> construct */ 61935500Sbostic --squest; 62024453Smckusick if (ps.want_blank) 6218800Smckusick *e_code++ = ' '; 62235500Sbostic *e_code++ = ':'; 62324453Smckusick ps.want_blank = true; 6248800Smckusick break; 62535500Sbostic } 62635500Sbostic if (ps.in_decl) { 62735500Sbostic *e_code++ = ':'; 62824453Smckusick ps.want_blank = false; 6298800Smckusick break; 63035500Sbostic } 63135500Sbostic ps.in_stmt = false; /* seeing a label does not imply we are in a 63235500Sbostic * stmt */ 63335500Sbostic for (t_ptr = s_code; *t_ptr; ++t_ptr) 63435500Sbostic *e_lab++ = *t_ptr; /* turn everything so far into a label */ 63535500Sbostic e_code = s_code; 63635500Sbostic *e_lab++ = ':'; 63735500Sbostic *e_lab++ = ' '; 63835500Sbostic *e_lab = '\0'; 6398800Smckusick 64035500Sbostic force_nl = ps.pcase = scase; /* ps.pcase will be used by 64135500Sbostic * dump_line to decide how to 64235500Sbostic * indent the label. force_nl 64335500Sbostic * will force a case n: to be 64435500Sbostic * on a line by itself */ 64535500Sbostic scase = false; 64635500Sbostic ps.want_blank = false; 64735500Sbostic break; 6488800Smckusick 64935500Sbostic case semicolon: /* got a ';' */ 65035500Sbostic ps.in_or_st = false;/* we are not in an initialization or 65135500Sbostic * structure declaration */ 65235500Sbostic scase = false; /* these will only need resetting in a error */ 65335500Sbostic squest = 0; 65438011Sbostic if (ps.last_token == rparen && rparen_count == 0) 65535500Sbostic ps.in_parameter_declaration = 0; 65635500Sbostic ps.cast_mask = 0; 65735500Sbostic ps.sizeof_mask = 0; 65835500Sbostic ps.block_init = 0; 65935500Sbostic ps.block_init_level = 0; 66035500Sbostic ps.just_saw_decl--; 6618800Smckusick 66235500Sbostic if (ps.in_decl && s_code == e_code && !ps.block_init) 66335500Sbostic while ((e_code - s_code) < (dec_ind - 1)) { 66440275Sbostic CHECK_SIZE_CODE; 66535500Sbostic *e_code++ = ' '; 66635500Sbostic } 6678800Smckusick 66835500Sbostic ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level 66935500Sbostic * structure declaration, we 67035500Sbostic * arent any more */ 67124453Smckusick 67235500Sbostic if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) { 6738800Smckusick 67435500Sbostic /* 67535500Sbostic * This should be true iff there were unbalanced parens in the 67635500Sbostic * stmt. It is a bit complicated, because the semicolon might 67735500Sbostic * be in a for stmt 67835500Sbostic */ 67935500Sbostic diag(1, "Unbalanced parens"); 68035500Sbostic ps.p_l_follow = 0; 68135500Sbostic if (sp_sw) { /* this is a check for a if, while, etc. with 68235500Sbostic * unbalanced parens */ 68335500Sbostic sp_sw = false; 68435500Sbostic parse(hd_type); /* dont lose the if, or whatever */ 6858800Smckusick } 68635500Sbostic } 68735500Sbostic *e_code++ = ';'; 68835500Sbostic ps.want_blank = true; 68935500Sbostic ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the 69035500Sbostic * middle of a stmt */ 6918800Smckusick 69235500Sbostic if (!sp_sw) { /* if not if for (;;) */ 69335500Sbostic parse(semicolon); /* let parser know about end of stmt */ 69435500Sbostic force_nl = true;/* force newline after a end of stmt */ 69535500Sbostic } 69635500Sbostic break; 6978800Smckusick 69835500Sbostic case lbrace: /* got a '{' */ 69935500Sbostic ps.in_stmt = false; /* dont indent the {} */ 70035500Sbostic if (!ps.block_init) 70135500Sbostic force_nl = true;/* force other stuff on same line as '{' onto 70235500Sbostic * new line */ 70335500Sbostic else if (ps.block_init_level <= 0) 70435500Sbostic ps.block_init_level = 1; 70535500Sbostic else 70635500Sbostic ps.block_init_level++; 7078800Smckusick 70835500Sbostic if (s_code != e_code && !ps.block_init) { 70935500Sbostic if (!btype_2) { 71035500Sbostic dump_line(); 71135500Sbostic ps.want_blank = false; 7128800Smckusick } 71335500Sbostic else if (ps.in_parameter_declaration && !ps.in_or_st) { 71435500Sbostic ps.i_l_follow = 0; 71535500Sbostic dump_line(); 71635500Sbostic ps.want_blank = false; 7178800Smckusick } 71835500Sbostic } 71935500Sbostic if (ps.in_parameter_declaration) 72035500Sbostic prefix_blankline_requested = 0; 7218800Smckusick 72235500Sbostic if (ps.p_l_follow > 0) { /* check for preceeding unbalanced 72335500Sbostic * parens */ 72435500Sbostic diag(1, "Unbalanced parens"); 72535500Sbostic ps.p_l_follow = 0; 72635500Sbostic if (sp_sw) { /* check for unclosed if, for, etc. */ 7278800Smckusick sp_sw = false; 72835500Sbostic parse(hd_type); 72935500Sbostic ps.ind_level = ps.i_l_follow; 7308800Smckusick } 73135500Sbostic } 73235500Sbostic if (s_code == e_code) 73335500Sbostic ps.ind_stmt = false; /* dont put extra indentation on line 73435500Sbostic * with '{' */ 73535500Sbostic if (ps.in_decl && ps.in_or_st) { /* this is either a structure 73635500Sbostic * declaration or an init */ 73735500Sbostic di_stack[ps.dec_nest++] = dec_ind; 73835500Sbostic /* ? dec_ind = 0; */ 73935500Sbostic } 74035500Sbostic else { 74135500Sbostic ps.decl_on_line = false; /* we cant be in the middle of 74235500Sbostic * a declaration, so dont do 74335500Sbostic * special indentation of 74435500Sbostic * comments */ 74535500Sbostic if (blanklines_after_declarations_at_proctop 74635500Sbostic && ps.in_parameter_declaration) 74724453Smckusick postfix_blankline_requested = 1; 74835500Sbostic ps.in_parameter_declaration = 0; 74935500Sbostic } 75035500Sbostic dec_ind = 0; 75135500Sbostic parse(lbrace); /* let parser know about this */ 75235500Sbostic if (ps.want_blank) /* put a blank before '{' if '{' is not at 75335500Sbostic * start of line */ 75435500Sbostic *e_code++ = ' '; 75535500Sbostic ps.want_blank = false; 75635500Sbostic *e_code++ = '{'; 75735500Sbostic ps.just_saw_decl = 0; 75835500Sbostic break; 7598800Smckusick 76035500Sbostic case rbrace: /* got a '}' */ 76135500Sbostic if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be 76235500Sbostic * omitted in 76335500Sbostic * declarations */ 76435500Sbostic parse(semicolon); 76535500Sbostic if (ps.p_l_follow) {/* check for unclosed if, for, else. */ 76635500Sbostic diag(1, "Unbalanced parens"); 76735500Sbostic ps.p_l_follow = 0; 76835500Sbostic sp_sw = false; 76935500Sbostic } 77035500Sbostic ps.just_saw_decl = 0; 77135500Sbostic ps.block_init_level--; 77235500Sbostic if (s_code != e_code && !ps.block_init) { /* '}' must be first on 77335500Sbostic * line */ 77435500Sbostic if (verbose) 77535500Sbostic diag(0, "Line broken"); 77635500Sbostic dump_line(); 77735500Sbostic } 77835500Sbostic *e_code++ = '}'; 77935500Sbostic ps.want_blank = true; 78035500Sbostic ps.in_stmt = ps.ind_stmt = false; 78135500Sbostic if (ps.dec_nest > 0) { /* we are in multi-level structure 78235500Sbostic * declaration */ 78335500Sbostic dec_ind = di_stack[--ps.dec_nest]; 78435500Sbostic if (ps.dec_nest == 0 && !ps.in_parameter_declaration) 78535500Sbostic ps.just_saw_decl = 2; 78635500Sbostic ps.in_decl = true; 78735500Sbostic } 78835500Sbostic prefix_blankline_requested = 0; 78935500Sbostic parse(rbrace); /* let parser know about this */ 79035500Sbostic ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead 79135500Sbostic && ps.il[ps.tos] >= ps.ind_level; 79235500Sbostic if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0) 79335500Sbostic postfix_blankline_requested = 1; 79435500Sbostic break; 7958800Smckusick 79635500Sbostic case swstmt: /* got keyword "switch" */ 79735500Sbostic sp_sw = true; 79835500Sbostic hd_type = swstmt; /* keep this for when we have seen the 79935500Sbostic * expression */ 80035500Sbostic goto copy_id; /* go move the token into buffer */ 80135500Sbostic 80235500Sbostic case sp_paren: /* token is if, while, for */ 80335500Sbostic sp_sw = true; /* the interesting stuff is done after the 80424453Smckusick * expression is scanned */ 80535500Sbostic hd_type = (*token == 'i' ? ifstmt : 80635500Sbostic (*token == 'w' ? whilestmt : forstmt)); 8078800Smckusick 80835500Sbostic /* 80935500Sbostic * remember the type of header for later use by parser 81035500Sbostic */ 81135500Sbostic goto copy_id; /* copy the token into line */ 81224453Smckusick 81335500Sbostic case sp_nparen: /* got else, do */ 81435500Sbostic ps.in_stmt = false; 81535500Sbostic if (*token == 'e') { 81635500Sbostic if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) { 81735500Sbostic if (verbose) 81835500Sbostic diag(0, "Line broken"); 81935500Sbostic dump_line();/* make sure this starts a line */ 82035500Sbostic ps.want_blank = false; 8218800Smckusick } 82235500Sbostic force_nl = true;/* also, following stuff must go onto new line */ 82335500Sbostic last_else = 1; 82435500Sbostic parse(elselit); 82535500Sbostic } 82635500Sbostic else { 82735500Sbostic if (e_code != s_code) { /* make sure this starts a line */ 82835500Sbostic if (verbose) 82935500Sbostic diag(0, "Line broken"); 83035500Sbostic dump_line(); 83135500Sbostic ps.want_blank = false; 83235500Sbostic } 83335500Sbostic force_nl = true;/* also, following stuff must go onto new line */ 83435500Sbostic last_else = 0; 83535500Sbostic parse(dolit); 83635500Sbostic } 83735500Sbostic goto copy_id; /* move the token into line */ 8388800Smckusick 83935500Sbostic case decl: /* we have a declaration type (int, register, 84035500Sbostic * etc.) */ 84135500Sbostic parse(decl); /* let parser worry about indentation */ 84235500Sbostic if (ps.last_token == rparen && ps.tos <= 1) { 84335500Sbostic ps.in_parameter_declaration = 1; 84435500Sbostic if (s_code != e_code) { 84535500Sbostic dump_line(); 84635500Sbostic ps.want_blank = 0; 84724453Smckusick } 84835500Sbostic } 84935500Sbostic if (ps.in_parameter_declaration && ps.indent_parameters && ps.dec_nest == 0) { 85035500Sbostic ps.ind_level = ps.i_l_follow = 1; 85135500Sbostic ps.ind_stmt = 0; 85235500Sbostic } 85335500Sbostic ps.in_or_st = true; /* this might be a structure or initialization 85435500Sbostic * declaration */ 85535500Sbostic ps.in_decl = ps.decl_on_line = true; 85635500Sbostic if ( /* !ps.in_or_st && */ ps.dec_nest <= 0) 85735500Sbostic ps.just_saw_decl = 2; 85835500Sbostic prefix_blankline_requested = 0; 85935500Sbostic for (i = 0; token[i++];); /* get length of token */ 8608800Smckusick 86135500Sbostic /* 86235500Sbostic * dec_ind = e_code - s_code + (ps.decl_indent>i ? ps.decl_indent 86335500Sbostic * : i); 86435500Sbostic */ 86535500Sbostic dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i; 86635500Sbostic goto copy_id; 8678800Smckusick 86835500Sbostic case ident: /* got an identifier or constant */ 86935500Sbostic if (ps.in_decl) { /* if we are in a declaration, we must indent 87035500Sbostic * identifier */ 87124453Smckusick if (ps.want_blank) 8728800Smckusick *e_code++ = ' '; 87335500Sbostic ps.want_blank = false; 87435500Sbostic if (is_procname == 0 || !procnames_start_line) { 87535500Sbostic if (!ps.block_init) 87635500Sbostic if (troff && !ps.dumped_decl_indent) { 87735500Sbostic sprintf(e_code, "\n.De %dp+\200p\n", dec_ind * 7); 87835500Sbostic ps.dumped_decl_indent = 1; 87935500Sbostic e_code += strlen(e_code); 88035500Sbostic } 88135500Sbostic else 88235500Sbostic while ((e_code - s_code) < dec_ind) { 88340275Sbostic CHECK_SIZE_CODE; 88435500Sbostic *e_code++ = ' '; 88535500Sbostic } 88624453Smckusick } 88735500Sbostic else { 88835500Sbostic if (dec_ind && s_code != e_code) 88935500Sbostic dump_line(); 89035500Sbostic dec_ind = 0; 89135500Sbostic ps.want_blank = false; 89235500Sbostic } 89335500Sbostic } 89435500Sbostic else if (sp_sw && ps.p_l_follow == 0) { 89535500Sbostic sp_sw = false; 89635500Sbostic force_nl = true; 89735500Sbostic ps.last_u_d = true; 89835500Sbostic ps.in_stmt = false; 89935500Sbostic parse(hd_type); 90035500Sbostic } 90135500Sbostic copy_id: 90235500Sbostic if (ps.want_blank) 90335500Sbostic *e_code++ = ' '; 90435500Sbostic if (troff && ps.its_a_keyword) { 90535500Sbostic e_code = chfont(&bodyf, &keywordf, e_code); 90635500Sbostic for (t_ptr = token; *t_ptr; ++t_ptr) { 90740275Sbostic CHECK_SIZE_CODE; 90835500Sbostic *e_code++ = keywordf.allcaps && islower(*t_ptr) 90935500Sbostic ? toupper(*t_ptr) : *t_ptr; 91035500Sbostic } 91135500Sbostic e_code = chfont(&keywordf, &bodyf, e_code); 91235500Sbostic } 91335500Sbostic else 91435500Sbostic for (t_ptr = token; *t_ptr; ++t_ptr) { 91540275Sbostic CHECK_SIZE_CODE; 9168800Smckusick *e_code++ = *t_ptr; 91724453Smckusick } 91835500Sbostic ps.want_blank = true; 91935500Sbostic break; 9208800Smckusick 92135500Sbostic case period: /* treat a period kind of like a binary 92224453Smckusick * operation */ 92335500Sbostic *e_code++ = '.'; /* move the period into line */ 92435500Sbostic ps.want_blank = false; /* dont put a blank after a period */ 92535500Sbostic break; 9268800Smckusick 92735500Sbostic case comma: 92835500Sbostic ps.want_blank = (s_code != e_code); /* only put blank after comma 92935500Sbostic * if comma does not start the 93035500Sbostic * line */ 93135500Sbostic if (ps.in_decl && is_procname == 0 && !ps.block_init) 93235500Sbostic while ((e_code - s_code) < (dec_ind - 1)) { 93340275Sbostic CHECK_SIZE_CODE; 93435500Sbostic *e_code++ = ' '; 93535500Sbostic } 9368800Smckusick 93735500Sbostic *e_code++ = ','; 93835500Sbostic if (ps.p_l_follow == 0) { 93935500Sbostic if (ps.block_init_level <= 0) 94024453Smckusick ps.block_init = 0; 94138011Sbostic if (break_comma && (!ps.leave_comma || compute_code_target() + (e_code - s_code) > max_col - 8)) 94235500Sbostic force_nl = true; 94335500Sbostic } 94435500Sbostic break; 9458800Smckusick 94635500Sbostic case preesc: /* got the character '#' */ 94735500Sbostic if ((s_com != e_com) || 94824453Smckusick (s_lab != e_lab) || 94924453Smckusick (s_code != e_code)) 95035500Sbostic dump_line(); 95135500Sbostic *e_lab++ = '#'; /* move whole line to 'label' buffer */ 95235500Sbostic { 95335500Sbostic int in_comment = 0; 95435500Sbostic int com_start = 0; 95535500Sbostic char quote = 0; 95635500Sbostic int com_end = 0; 9578800Smckusick 95838011Sbostic while (*buf_ptr == ' ' || *buf_ptr == '\t') { 95938011Sbostic buf_ptr++; 96038011Sbostic if (buf_ptr >= buf_end) 96138011Sbostic fill_buffer(); 96238011Sbostic } 96335500Sbostic while (*buf_ptr != '\n' || in_comment) { 96440275Sbostic CHECK_SIZE_LAB; 96535500Sbostic *e_lab = *buf_ptr++; 96635500Sbostic if (buf_ptr >= buf_end) 96735500Sbostic fill_buffer(); 96835500Sbostic switch (*e_lab++) { 96935500Sbostic case BACKSLASH: 97035500Sbostic if (troff) 97135500Sbostic *e_lab++ = BACKSLASH; 97235500Sbostic if (!in_comment) { 97335500Sbostic *e_lab++ = *buf_ptr++; 97435500Sbostic if (buf_ptr >= buf_end) 97535500Sbostic fill_buffer(); 97624453Smckusick } 97735500Sbostic break; 97835500Sbostic case '/': 97935500Sbostic if (*buf_ptr == '*' && !in_comment && !quote) { 98035500Sbostic in_comment = 1; 98135500Sbostic *e_lab++ = *buf_ptr++; 98235500Sbostic com_start = e_lab - s_lab - 2; 98335500Sbostic } 98435500Sbostic break; 98535500Sbostic case '"': 98635500Sbostic if (quote == '"') 98735500Sbostic quote = 0; 98835500Sbostic break; 98935500Sbostic case '\'': 99035500Sbostic if (quote == '\'') 99135500Sbostic quote = 0; 99235500Sbostic break; 99335500Sbostic case '*': 99435500Sbostic if (*buf_ptr == '/' && in_comment) { 99535500Sbostic in_comment = 0; 99635500Sbostic *e_lab++ = *buf_ptr++; 99735500Sbostic com_end = e_lab - s_lab; 99835500Sbostic } 99935500Sbostic break; 10008800Smckusick } 100135500Sbostic } 100235500Sbostic 100335500Sbostic while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 100435500Sbostic e_lab--; 100535500Sbostic if (e_lab - s_lab == com_end && bp_save == 0) { /* comment on 100624453Smckusick * preprocessor line */ 100735500Sbostic if (sc_end == 0) /* if this is the first comment, we 100835500Sbostic * must set up the buffer */ 100935500Sbostic sc_end = &(save_com[0]); 101035500Sbostic else { 101135500Sbostic *sc_end++ = '\n'; /* add newline between 101224453Smckusick * comments */ 101335500Sbostic *sc_end++ = ' '; 101435500Sbostic --line_no; 101524453Smckusick } 101635500Sbostic bcopy(s_lab + com_start, sc_end, com_end - com_start); 101735500Sbostic sc_end += com_end - com_start; 101835500Sbostic if (sc_end >= &save_com[sc_size]) 101935500Sbostic abort(); 102035500Sbostic e_lab = s_lab + com_start; 102135500Sbostic while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 102235500Sbostic e_lab--; 102335500Sbostic bp_save = buf_ptr; /* save current input buffer */ 102435500Sbostic be_save = buf_end; 102535500Sbostic buf_ptr = save_com; /* fix so that subsequent calls to 102635500Sbostic * lexi will take tokens out of 102735500Sbostic * save_com */ 102835500Sbostic *sc_end++ = ' '; /* add trailing blank, just in case */ 102935500Sbostic buf_end = sc_end; 103035500Sbostic sc_end = 0; 10318800Smckusick } 103235500Sbostic *e_lab = '\0'; /* null terminate line */ 103335500Sbostic ps.pcase = false; 103435500Sbostic } 103535500Sbostic 103635500Sbostic if (strncmp(s_lab, "#if", 3) == 0) { 103735500Sbostic if (blanklines_around_conditional_compilation) { 103835500Sbostic register c; 103935500Sbostic prefix_blankline_requested++; 104035500Sbostic while ((c = getc(input)) == '\n'); 104135500Sbostic ungetc(c, input); 104235500Sbostic } 104335500Sbostic if (ifdef_level < sizeof state_stack / sizeof state_stack[0]) { 104435500Sbostic match_state[ifdef_level].tos = -1; 104535500Sbostic state_stack[ifdef_level++] = ps; 104635500Sbostic } 104735500Sbostic else 104835500Sbostic diag(1, "#if stack overflow"); 104935500Sbostic } 105035500Sbostic else if (strncmp(s_lab, "#else", 5) == 0) 105135500Sbostic if (ifdef_level <= 0) 105235500Sbostic diag(1, "Unmatched #else"); 105335500Sbostic else { 105435500Sbostic match_state[ifdef_level - 1] = ps; 105535500Sbostic ps = state_stack[ifdef_level - 1]; 105635500Sbostic } 105735500Sbostic else if (strncmp(s_lab, "#endif", 6) == 0) { 105835500Sbostic if (ifdef_level <= 0) 105935500Sbostic diag(1, "Unmatched #endif"); 106035500Sbostic else { 106135500Sbostic ifdef_level--; 106235500Sbostic 106324453Smckusick #ifdef undef 106435500Sbostic /* 106535500Sbostic * This match needs to be more intelligent before the 106635500Sbostic * message is useful 106735500Sbostic */ 106835500Sbostic if (match_state[ifdef_level].tos >= 0 106935500Sbostic && bcmp(&ps, &match_state[ifdef_level], sizeof ps)) 107035500Sbostic diag(0, "Syntactically inconsistant #ifdef alternatives."); 107124453Smckusick #endif 107235500Sbostic } 107335500Sbostic if (blanklines_around_conditional_compilation) { 107435500Sbostic postfix_blankline_requested++; 107535500Sbostic n_real_blanklines = 0; 107635500Sbostic } 107735500Sbostic } 107835500Sbostic break; /* subsequent processing of the newline 107935500Sbostic * character will cause the line to be printed */ 10808800Smckusick 108135500Sbostic case comment: /* we have gotten a /* this is a biggie */ 108235500Sbostic if (flushed_nl) { /* we should force a broken line here */ 108335500Sbostic flushed_nl = false; 108435500Sbostic dump_line(); 108535500Sbostic ps.want_blank = false; /* dont insert blank at line start */ 108635500Sbostic force_nl = false; 108735500Sbostic } 108835500Sbostic pr_comment(); 108935500Sbostic break; 109024453Smckusick } /* end of big switch stmt */ 109135500Sbostic 109235500Sbostic *e_code = '\0'; /* make sure code section is null terminated */ 109324453Smckusick if (type_code != comment && type_code != newline && type_code != preesc) 109424453Smckusick ps.last_token = type_code; 109524453Smckusick } /* end of main while (1) loop */ 109636970Sbostic } 10978800Smckusick 10988800Smckusick /* 109935500Sbostic * copy input file to backup file if in_name is /blah/blah/blah/file, then 110035500Sbostic * backup file will be ".Bfile" then make the backup file the input and 110135500Sbostic * original input file the output 11028800Smckusick */ 110324453Smckusick bakcopy() 110424453Smckusick { 110524453Smckusick int n, 110624453Smckusick bakchn; 110735500Sbostic char buff[8 * 1024]; 110824453Smckusick register char *p; 11098800Smckusick 111035500Sbostic /* construct file name .Bfile */ 111135500Sbostic for (p = in_name; *p; p++); /* skip to end of string */ 111235500Sbostic while (p > in_name && *p != '/') /* find last '/' */ 111335500Sbostic p--; 111435500Sbostic if (*p == '/') 11158800Smckusick p++; 111624453Smckusick sprintf(bakfile, "%s.BAK", p); 11178800Smckusick 111824453Smckusick /* copy in_name to backup file */ 111924453Smckusick bakchn = creat(bakfile, 0600); 112036970Sbostic if (bakchn < 0) 112136970Sbostic err(bakfile); 112235500Sbostic while (n = read(fileno(input), buff, sizeof buff)) 112336970Sbostic if (write(bakchn, buff, n) != n) 112436970Sbostic err(bakfile); 112536970Sbostic if (n < 0) 112636970Sbostic err(in_name); 112724453Smckusick close(bakchn); 112824453Smckusick fclose(input); 11298800Smckusick 113024453Smckusick /* re-open backup file as the input file */ 113124453Smckusick input = fopen(bakfile, "r"); 113236970Sbostic if (input == 0) 113336970Sbostic err(bakfile); 113424453Smckusick /* now the original input file will be the output */ 113524453Smckusick output = fopen(in_name, "w"); 113635500Sbostic if (output == 0) { 113724453Smckusick unlink(bakfile); 113836970Sbostic err(in_name); 11398800Smckusick } 11408800Smckusick } 114136970Sbostic 114236970Sbostic err(msg) 114336970Sbostic char *msg; 114436970Sbostic { 114536970Sbostic extern int errno; 114636970Sbostic char *strerror(); 114736970Sbostic 114836970Sbostic (void)fprintf(stderr, "indent: %s: %s\n", msg, strerror(errno)); 114936970Sbostic exit(1); 115036970Sbostic } 1151