121968Sdist /*
235500Sbostic * Copyright (c) 1985 Sun Microsystems, Inc.
333767Sbostic * Copyright (c) 1976 Board of Trustees of the University of Illinois.
4*62550Sbostic * Copyright (c) 1980, 1993
5*62550Sbostic * The Regents of the University of California. All rights reserved.
633767Sbostic *
742686Sbostic * %sccs.include.redist.c%
821968Sdist */
98800Smckusick
1021968Sdist #ifndef lint
1121968Sdist char copyright[] =
1235500Sbostic "@(#) Copyright (c) 1985 Sun Microsystems, Inc.\n\
13*62550Sbostic @(#) Copyright (c) 1976 Board of Trustees of the University of Illinois.\n\
14*62550Sbostic @(#) Copyright (c) 1980, 1993\n\
15*62550Sbostic The Regents of the University of California. All rights reserved.\n";
1633767Sbostic #endif /* not lint */
1721968Sdist
1821968Sdist #ifndef lint
19*62550Sbostic static char sccsid[] = "@(#)indent.c 5.17 (Berkeley) 06/07/93";
2033767Sbostic #endif /* not lint */
2121968Sdist
2236970Sbostic #include <sys/param.h>
2346695Sbostic #include <fcntl.h>
2446695Sbostic #include <unistd.h>
2546695Sbostic #include <stdio.h>
2646695Sbostic #include <stdlib.h>
2746695Sbostic #include <string.h>
2835505Sbostic #include "indent_globs.h"
2935505Sbostic #include "indent_codes.h"
3035500Sbostic #include <ctype.h>
318800Smckusick
3235500Sbostic char *in_name = "Standard Input"; /* will always point to name of input
3335500Sbostic * file */
3435500Sbostic char *out_name = "Standard Output"; /* will always point to name
3535500Sbostic * of output file */
3635500Sbostic char bakfile[MAXPATHLEN] = "";
378800Smckusick
main(argc,argv)3824453Smckusick main(argc, argv)
3924453Smckusick int argc;
4024453Smckusick char **argv;
418800Smckusick {
428800Smckusick
4335505Sbostic extern int found_err; /* flag set in diag() on error */
4424453Smckusick int dec_ind; /* current indentation for declarations */
4524453Smckusick int di_stack[20]; /* a stack of structure indentation levels */
4635500Sbostic int flushed_nl; /* used when buffering up comments to remember
4735500Sbostic * that a newline was passed over */
4824453Smckusick int force_nl; /* when true, code must be broken */
4935500Sbostic int hd_type; /* used to store type of stmt for if (...),
5035500Sbostic * for (...), etc */
5124453Smckusick register int i; /* local loop counter */
5235500Sbostic int scase; /* set to true when we see a case, so we will
5335500Sbostic * know what to do with the following colon */
5424453Smckusick int sp_sw; /* when true, we are in the expressin of
5524453Smckusick * if(...), while(...), etc. */
5624453Smckusick int squest; /* when this is positive, we have seen a ?
5724453Smckusick * without the matching : in a <c>?<s>:<s>
5824453Smckusick * construct */
5924453Smckusick register char *t_ptr; /* used for copying tokens */
6024453Smckusick int type_code; /* the type of token, returned by lexi */
618800Smckusick
6224453Smckusick int last_else = 0; /* true iff last keyword was an else */
638800Smckusick
648800Smckusick
6524453Smckusick /*-----------------------------------------------*\
6624648Smckusick | INITIALIZATION |
6724648Smckusick \*-----------------------------------------------*/
688800Smckusick
698800Smckusick
7024453Smckusick ps.p_stack[0] = stmt; /* this is the parser's stack */
7135500Sbostic ps.last_nl = true; /* this is true if the last thing scanned was
7235500Sbostic * a newline */
7324453Smckusick ps.last_token = semicolon;
7435500Sbostic combuf = (char *) malloc(bufsize);
7535500Sbostic labbuf = (char *) malloc(bufsize);
7635500Sbostic codebuf = (char *) malloc(bufsize);
7738011Sbostic tokenbuf = (char *) malloc(bufsize);
7835500Sbostic l_com = combuf + bufsize - 5;
7935500Sbostic l_lab = labbuf + bufsize - 5;
8035500Sbostic l_code = codebuf + bufsize - 5;
8138011Sbostic l_token = tokenbuf + bufsize - 5;
8224453Smckusick combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and
8324453Smckusick * comment buffers */
848800Smckusick combuf[1] = codebuf[1] = labbuf[1] = '\0';
8535500Sbostic ps.else_if = 1; /* Default else-if special processing to on */
868800Smckusick s_lab = e_lab = labbuf + 1;
878800Smckusick s_code = e_code = codebuf + 1;
888800Smckusick s_com = e_com = combuf + 1;
8938011Sbostic s_token = e_token = tokenbuf + 1;
908800Smckusick
9138011Sbostic in_buffer = (char *) malloc(10);
9238011Sbostic in_buffer_limit = in_buffer + 8;
938800Smckusick buf_ptr = buf_end = in_buffer;
948800Smckusick line_no = 1;
9524453Smckusick had_eof = ps.in_decl = ps.decl_on_line = break_comma = false;
968800Smckusick sp_sw = force_nl = false;
9724453Smckusick ps.in_or_st = false;
9824453Smckusick ps.bl_line = true;
998800Smckusick dec_ind = 0;
10024453Smckusick di_stack[ps.dec_nest = 0] = 0;
10124453Smckusick ps.want_blank = ps.in_stmt = ps.ind_stmt = false;
1028800Smckusick
1038800Smckusick
10424453Smckusick scase = ps.pcase = false;
1058800Smckusick squest = 0;
1068800Smckusick sc_end = 0;
1078800Smckusick bp_save = 0;
1088800Smckusick be_save = 0;
1098800Smckusick
11024453Smckusick output = 0;
1118800Smckusick
1128800Smckusick
1138800Smckusick
11424453Smckusick /*--------------------------------------------------*\
11535500Sbostic | COMMAND LINE SCAN |
11624648Smckusick \*--------------------------------------------------*/
1178800Smckusick
11835500Sbostic #ifdef undef
11935500Sbostic max_col = 78; /* -l78 */
12035500Sbostic lineup_to_parens = 1; /* -lp */
12135500Sbostic ps.ljust_decl = 0; /* -ndj */
12235500Sbostic ps.com_ind = 33; /* -c33 */
12335500Sbostic star_comment_cont = 1; /* -sc */
12435500Sbostic ps.ind_size = 8; /* -i8 */
12535500Sbostic verbose = 0;
12635500Sbostic ps.decl_indent = 16; /* -di16 */
12735500Sbostic ps.indent_parameters = 1; /* -ip */
12835500Sbostic ps.decl_com_ind = 0; /* if this is not set to some positive value
12935500Sbostic * by an arg, we will set this equal to
13035500Sbostic * ps.com_ind */
13135500Sbostic btype_2 = 1; /* -br */
13235500Sbostic cuddle_else = 1; /* -ce */
13335500Sbostic ps.unindent_displace = 0; /* -d0 */
13435500Sbostic ps.case_indent = 0; /* -cli0 */
13535500Sbostic format_col1_comments = 1; /* -fc1 */
13635500Sbostic procnames_start_line = 1; /* -psl */
13735500Sbostic proc_calls_space = 0; /* -npcs */
13835500Sbostic comment_delimiter_on_blankline = 1; /* -cdb */
13935500Sbostic ps.leave_comma = 1; /* -nbc */
14035500Sbostic #endif
1418800Smckusick
14224453Smckusick for (i = 1; i < argc; ++i)
14324453Smckusick if (strcmp(argv[i], "-npro") == 0)
14424453Smckusick break;
14535500Sbostic set_defaults();
14624453Smckusick if (i >= argc)
14724453Smckusick set_profile();
1488800Smckusick
1498800Smckusick for (i = 1; i < argc; ++i) {
15024453Smckusick
15124453Smckusick /*
15235500Sbostic * look thru args (if any) for changes to defaults
15324453Smckusick */
1548800Smckusick if (argv[i][0] != '-') {/* no flag on parameter */
15524453Smckusick if (input == 0) { /* we must have the input file */
15624453Smckusick in_name = argv[i]; /* remember name of input file */
15724453Smckusick input = fopen(in_name, "r");
15836970Sbostic if (input == 0) /* check for open error */
15936970Sbostic err(in_name);
1608800Smckusick continue;
16135500Sbostic }
16235500Sbostic else if (output == 0) { /* we have the output file */
16324453Smckusick out_name = argv[i]; /* remember name of output file */
16424453Smckusick if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite
16524453Smckusick * the file */
16624648Smckusick fprintf(stderr, "indent: input and output files must be different\n");
16724648Smckusick exit(1);
16824453Smckusick }
16924453Smckusick output = fopen(out_name, "w");
17036970Sbostic if (output == 0) /* check for create error */
17136970Sbostic err(out_name);
17224453Smckusick continue;
1738800Smckusick }
17424648Smckusick fprintf(stderr, "indent: unknown parameter: %s\n", argv[i]);
17524648Smckusick exit(1);
17635500Sbostic }
17735500Sbostic else
17824453Smckusick set_option(argv[i]);
17924453Smckusick } /* end of for */
18024453Smckusick if (input == 0) {
18135500Sbostic fprintf(stderr, "indent: usage: indent file [ outfile ] [ options ]\n");
18224648Smckusick exit(1);
18324453Smckusick }
18424453Smckusick if (output == 0)
18524453Smckusick if (troff)
18624453Smckusick output = stdout;
18724453Smckusick else {
18824453Smckusick out_name = in_name;
18924453Smckusick bakcopy();
1908800Smckusick }
19124453Smckusick if (ps.com_ind <= 1)
19235500Sbostic ps.com_ind = 2; /* dont put normal comments before column 2 */
19335500Sbostic if (troff) {
19435500Sbostic if (bodyf.font[0] == 0)
19535500Sbostic parsefont(&bodyf, "R");
19635500Sbostic if (scomf.font[0] == 0)
19735500Sbostic parsefont(&scomf, "I");
19835500Sbostic if (blkcomf.font[0] == 0)
19935500Sbostic blkcomf = scomf, blkcomf.size += 2;
20035500Sbostic if (boxcomf.font[0] == 0)
20135500Sbostic boxcomf = blkcomf;
20235500Sbostic if (stringf.font[0] == 0)
20335500Sbostic parsefont(&stringf, "L");
20435500Sbostic if (keywordf.font[0] == 0)
20535500Sbostic parsefont(&keywordf, "B");
20635500Sbostic writefdef(&bodyf, 'B');
20735500Sbostic writefdef(&scomf, 'C');
20835500Sbostic writefdef(&blkcomf, 'L');
20935500Sbostic writefdef(&boxcomf, 'X');
21035500Sbostic writefdef(&stringf, 'S');
21135500Sbostic writefdef(&keywordf, 'K');
21235500Sbostic }
21324453Smckusick if (block_comment_max_col <= 0)
21424453Smckusick block_comment_max_col = max_col;
21524453Smckusick if (ps.decl_com_ind <= 0) /* if not specified by user, set this */
21635500Sbostic ps.decl_com_ind = ps.ljust_decl ? (ps.com_ind <= 10 ? 2 : ps.com_ind - 8) : ps.com_ind;
21724453Smckusick if (continuation_indent == 0)
21824453Smckusick continuation_indent = ps.ind_size;
21935500Sbostic fill_buffer(); /* get first batch of stuff into input buffer */
2208800Smckusick
22124453Smckusick parse(semicolon);
22224453Smckusick {
22324453Smckusick register char *p = buf_ptr;
22424453Smckusick register col = 1;
2258800Smckusick
22624453Smckusick while (1) {
22724453Smckusick if (*p == ' ')
22824453Smckusick col++;
22924453Smckusick else if (*p == '\t')
23024453Smckusick col = ((col - 1) & ~7) + 9;
23124453Smckusick else
23224453Smckusick break;
23324453Smckusick p++;
23436970Sbostic }
23524453Smckusick if (col > ps.ind_size)
23624453Smckusick ps.ind_level = ps.i_l_follow = col / ps.ind_size;
2378800Smckusick }
23824453Smckusick if (troff) {
23924453Smckusick register char *p = in_name,
24024453Smckusick *beg = in_name;
24124453Smckusick
24224453Smckusick while (*p)
24324453Smckusick if (*p++ == '/')
24424453Smckusick beg = p;
24524453Smckusick fprintf(output, ".Fn \"%s\"\n", beg);
2468800Smckusick }
24724453Smckusick /*
24835500Sbostic * START OF MAIN LOOP
24924453Smckusick */
2508800Smckusick
25135500Sbostic while (1) { /* this is the main loop. it will go until we
25235500Sbostic * reach eof */
25324453Smckusick int is_procname;
2548800Smckusick
25524453Smckusick type_code = lexi(); /* lexi reads one token. The actual
25635500Sbostic * characters read are stored in "token". lexi
25735500Sbostic * returns a code indicating the type of token */
25824453Smckusick is_procname = ps.procname[0];
2598800Smckusick
26024453Smckusick /*
26135500Sbostic * The following code moves everything following an if (), while (),
26235500Sbostic * else, etc. up to the start of the following stmt to a buffer. This
26335500Sbostic * allows proper handling of both kinds of brace placement.
26424453Smckusick */
2658800Smckusick
2668800Smckusick flushed_nl = false;
26724453Smckusick while (ps.search_brace) { /* if we scanned an if(), while(),
26835500Sbostic * etc., we might need to copy stuff
26935500Sbostic * into a buffer we must loop, copying
27035500Sbostic * stuff into save_com, until we find
27135500Sbostic * the start of the stmt which follows
27224453Smckusick * the if, or whatever */
2738800Smckusick switch (type_code) {
27435500Sbostic case newline:
27535500Sbostic ++line_no;
27635500Sbostic flushed_nl = true;
27735500Sbostic case form_feed:
27835500Sbostic break; /* form feeds and newlines found here will be
27935500Sbostic * ignored */
2808800Smckusick
28135500Sbostic case lbrace: /* this is a brace that starts the compound
28235500Sbostic * stmt */
28335500Sbostic if (sc_end == 0) { /* ignore buffering if a comment wasnt
28435500Sbostic * stored up */
28535500Sbostic ps.search_brace = false;
28635500Sbostic goto check_type;
28735500Sbostic }
28835500Sbostic if (btype_2) {
28935500Sbostic save_com[0] = '{'; /* we either want to put the brace
29035500Sbostic * right after the if */
29135500Sbostic goto sw_buffer; /* go to common code to get out of
29224453Smckusick * this loop */
29335500Sbostic }
29435500Sbostic case comment: /* we have a comment, so we must copy it into
29535500Sbostic * the buffer */
29635500Sbostic if (!flushed_nl || sc_end != 0) {
29735500Sbostic if (sc_end == 0) { /* if this is the first comment, we
29835500Sbostic * must set up the buffer */
29935500Sbostic save_com[0] = save_com[1] = ' ';
30035500Sbostic sc_end = &(save_com[2]);
3018800Smckusick }
30235500Sbostic else {
30335500Sbostic *sc_end++ = '\n'; /* add newline between
30424453Smckusick * comments */
30535500Sbostic *sc_end++ = ' ';
30635500Sbostic --line_no;
30735500Sbostic }
30835500Sbostic *sc_end++ = '/'; /* copy in start of comment */
30935500Sbostic *sc_end++ = '*';
3108800Smckusick
31135500Sbostic for (;;) { /* loop until we get to the end of the comment */
31235500Sbostic *sc_end = *buf_ptr++;
31335500Sbostic if (buf_ptr >= buf_end)
31435500Sbostic fill_buffer();
31524453Smckusick
31635500Sbostic if (*sc_end++ == '*' && *buf_ptr == '/')
31735500Sbostic break; /* we are at end of comment */
31824453Smckusick
31935500Sbostic if (sc_end >= &(save_com[sc_size])) { /* check for temp buffer
32035500Sbostic * overflow */
32135500Sbostic diag(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever.");
32235500Sbostic fflush(output);
32335500Sbostic exit(1);
32424453Smckusick }
32524453Smckusick }
32635500Sbostic *sc_end++ = '/'; /* add ending slash */
32735500Sbostic if (++buf_ptr >= buf_end) /* get past / in buffer */
32835500Sbostic fill_buffer();
32935500Sbostic break;
33035500Sbostic }
33135500Sbostic default: /* it is the start of a normal statment */
33235500Sbostic if (flushed_nl) /* if we flushed a newline, make sure it is
33335500Sbostic * put back */
33435500Sbostic force_nl = true;
33535500Sbostic if (type_code == sp_paren && *token == 'i'
33624453Smckusick && last_else && ps.else_if
33724453Smckusick || type_code == sp_nparen && *token == 'e'
33824453Smckusick && e_code != s_code && e_code[-1] == '}')
33935500Sbostic force_nl = false;
3408800Smckusick
34135500Sbostic if (sc_end == 0) { /* ignore buffering if comment wasnt
34235500Sbostic * saved up */
34335500Sbostic ps.search_brace = false;
34435500Sbostic goto check_type;
34535500Sbostic }
34635500Sbostic if (force_nl) { /* if we should insert a nl here, put it into
34735500Sbostic * the buffer */
34835500Sbostic force_nl = false;
34935500Sbostic --line_no; /* this will be re-increased when the nl is
35035500Sbostic * read from the buffer */
35135500Sbostic *sc_end++ = '\n';
35235500Sbostic *sc_end++ = ' ';
35335500Sbostic if (verbose && !flushed_nl) /* print error msg if the line
35435500Sbostic * was not already broken */
35535500Sbostic diag(0, "Line broken");
35635500Sbostic flushed_nl = false;
35735500Sbostic }
35835500Sbostic for (t_ptr = token; *t_ptr; ++t_ptr)
35935500Sbostic *sc_end++ = *t_ptr; /* copy token into temp buffer */
36035500Sbostic ps.procname[0] = 0;
3618800Smckusick
36235500Sbostic sw_buffer:
36335500Sbostic ps.search_brace = false; /* stop looking for start of
36435500Sbostic * stmt */
36535500Sbostic bp_save = buf_ptr; /* save current input buffer */
36635500Sbostic be_save = buf_end;
36735500Sbostic buf_ptr = save_com; /* fix so that subsequent calls to
36824453Smckusick * lexi will take tokens out of
36924453Smckusick * save_com */
37035500Sbostic *sc_end++ = ' ';/* add trailing blank, just in case */
37135500Sbostic buf_end = sc_end;
37235500Sbostic sc_end = 0;
37335500Sbostic break;
37424453Smckusick } /* end of switch */
37535500Sbostic if (type_code != 0) /* we must make this check, just in case there
37635500Sbostic * was an unexpected EOF */
37724453Smckusick type_code = lexi(); /* read another token */
37835500Sbostic /* if (ps.search_brace) ps.procname[0] = 0; */
37935500Sbostic if ((is_procname = ps.procname[0]) && flushed_nl
38035500Sbostic && !procnames_start_line && ps.in_decl
38135500Sbostic && type_code == ident)
38235500Sbostic flushed_nl = 0;
38335500Sbostic } /* end of while (search_brace) */
38424453Smckusick last_else = 0;
38524453Smckusick check_type:
38624453Smckusick if (type_code == 0) { /* we got eof */
3878800Smckusick if (s_lab != e_lab || s_code != e_code
38835500Sbostic || s_com != e_com) /* must dump end of line */
38924453Smckusick dump_line();
39024453Smckusick if (ps.tos > 1) /* check for balanced braces */
39124453Smckusick diag(1, "Stuff missing from end of file.");
3928800Smckusick
3938800Smckusick if (verbose) {
39424453Smckusick printf("There were %d output lines and %d comments\n",
39524453Smckusick ps.out_lines, ps.out_coms);
39624453Smckusick printf("(Lines with comments)/(Lines with code): %6.3f\n",
39724453Smckusick (1.0 * ps.com_lines) / code_lines);
3988800Smckusick }
39924453Smckusick fflush(output);
40035505Sbostic exit(found_err);
4018800Smckusick }
4028800Smckusick if (
40335500Sbostic (type_code != comment) &&
40435500Sbostic (type_code != newline) &&
40535500Sbostic (type_code != preesc) &&
40635500Sbostic (type_code != form_feed)) {
40735500Sbostic if (force_nl &&
40835500Sbostic (type_code != semicolon) &&
40935500Sbostic (type_code != lbrace || !btype_2)) {
41035500Sbostic /* we should force a broken line here */
4118800Smckusick if (verbose && !flushed_nl)
41224453Smckusick diag(0, "Line broken");
4138800Smckusick flushed_nl = false;
41424453Smckusick dump_line();
41524453Smckusick ps.want_blank = false; /* dont insert blank at line start */
4168800Smckusick force_nl = false;
4178800Smckusick }
41835500Sbostic ps.in_stmt = true; /* turn on flag which causes an extra level of
41935500Sbostic * indentation. this is turned off by a ; or
42035500Sbostic * '}' */
42135500Sbostic if (s_com != e_com) { /* the turkey has embedded a comment
42235500Sbostic * in a line. fix it */
4238800Smckusick *e_code++ = ' ';
42435500Sbostic for (t_ptr = s_com; *t_ptr; ++t_ptr) {
42540275Sbostic CHECK_SIZE_CODE;
4268800Smckusick *e_code++ = *t_ptr;
42735500Sbostic }
4288800Smckusick *e_code++ = ' ';
42924453Smckusick *e_code = '\0'; /* null terminate code sect */
43024453Smckusick ps.want_blank = false;
4318800Smckusick e_com = s_com;
4328800Smckusick }
43335500Sbostic }
43435500Sbostic else if (type_code != comment) /* preserve force_nl thru a comment */
43535500Sbostic force_nl = false; /* cancel forced newline after newline, form
43635500Sbostic * feed, etc */
4378800Smckusick
4388800Smckusick
4398800Smckusick
44035500Sbostic /*-----------------------------------------------------*\
44135500Sbostic | do switch on type of token scanned |
44235500Sbostic \*-----------------------------------------------------*/
44340275Sbostic CHECK_SIZE_CODE;
44424453Smckusick switch (type_code) { /* now, decide what to do with the token */
44524453Smckusick
44635500Sbostic case form_feed: /* found a form feed in line */
44735500Sbostic ps.use_ff = true; /* a form feed is treated much like a newline */
44835500Sbostic dump_line();
44935500Sbostic ps.want_blank = false;
45035500Sbostic break;
45135500Sbostic
45235500Sbostic case newline:
45335500Sbostic if (ps.last_token != comma || ps.p_l_follow > 0
45435500Sbostic || !ps.leave_comma || ps.block_init || !break_comma || s_com != e_com) {
45524453Smckusick dump_line();
45624453Smckusick ps.want_blank = false;
45735500Sbostic }
45835500Sbostic ++line_no; /* keep track of input line number */
45935500Sbostic break;
4608800Smckusick
46135500Sbostic case lparen: /* got a '(' or '[' */
46235500Sbostic ++ps.p_l_follow; /* count parens to make Healy happy */
46335500Sbostic if (ps.want_blank && *token != '[' &&
46435500Sbostic (ps.last_token != ident || proc_calls_space
46535500Sbostic || (ps.its_a_keyword && (!ps.sizeof_keyword || Bill_Shannon))))
46635500Sbostic *e_code++ = ' ';
46735500Sbostic if (ps.in_decl && !ps.block_init)
46835500Sbostic if (troff && !ps.dumped_decl_indent && !is_procname && ps.last_token == decl) {
46935500Sbostic ps.dumped_decl_indent = 1;
47035500Sbostic sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token);
47135500Sbostic e_code += strlen(e_code);
47224453Smckusick }
47335500Sbostic else {
47435500Sbostic while ((e_code - s_code) < dec_ind) {
47540275Sbostic CHECK_SIZE_CODE;
47635500Sbostic *e_code++ = ' ';
47735500Sbostic }
47824453Smckusick *e_code++ = token[0];
4798800Smckusick }
48035500Sbostic else
48135500Sbostic *e_code++ = token[0];
48235500Sbostic ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code;
48335500Sbostic if (sp_sw && ps.p_l_follow == 1 && extra_expression_indent
48435500Sbostic && ps.paren_indents[0] < 2 * ps.ind_size)
48535500Sbostic ps.paren_indents[0] = 2 * ps.ind_size;
48635500Sbostic ps.want_blank = false;
48735500Sbostic if (ps.in_or_st && *token == '(' && ps.tos <= 2) {
48835500Sbostic /*
48935500Sbostic * this is a kluge to make sure that declarations will be
49035500Sbostic * aligned right if proc decl has an explicit type on it, i.e.
49135500Sbostic * "int a(x) {..."
49235500Sbostic */
49335500Sbostic parse(semicolon); /* I said this was a kluge... */
49435500Sbostic ps.in_or_st = false; /* turn off flag for structure decl or
49535500Sbostic * initialization */
49635500Sbostic }
49735500Sbostic if (ps.sizeof_keyword)
49835500Sbostic ps.sizeof_mask |= 1 << ps.p_l_follow;
49935500Sbostic break;
5008800Smckusick
50135500Sbostic case rparen: /* got a ')' or ']' */
50238011Sbostic rparen_count--;
50335500Sbostic if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask) {
50435500Sbostic ps.last_u_d = true;
50535500Sbostic ps.cast_mask &= (1 << ps.p_l_follow) - 1;
50635500Sbostic }
50735500Sbostic ps.sizeof_mask &= (1 << ps.p_l_follow) - 1;
50835500Sbostic if (--ps.p_l_follow < 0) {
50935500Sbostic ps.p_l_follow = 0;
51035500Sbostic diag(0, "Extra %c", *token);
51135500Sbostic }
51235500Sbostic if (e_code == s_code) /* if the paren starts the line */
51335500Sbostic ps.paren_level = ps.p_l_follow; /* then indent it */
5148800Smckusick
51535500Sbostic *e_code++ = token[0];
51635500Sbostic ps.want_blank = true;
5178800Smckusick
51835500Sbostic if (sp_sw && (ps.p_l_follow == 0)) { /* check for end of if
51924453Smckusick * (...), or some such */
52035500Sbostic sp_sw = false;
52135500Sbostic force_nl = true;/* must force newline after if */
52235500Sbostic ps.last_u_d = true; /* inform lexi that a following
52324453Smckusick * operator is unary */
52435500Sbostic ps.in_stmt = false; /* dont use stmt continuation
52524453Smckusick * indentation */
5268800Smckusick
52735500Sbostic parse(hd_type); /* let parser worry about if, or whatever */
52835500Sbostic }
52935500Sbostic ps.search_brace = btype_2; /* this should insure that constructs
53035500Sbostic * such as main(){...} and int[]{...}
53135500Sbostic * have their braces put in the right
53235500Sbostic * place */
53335500Sbostic break;
5348800Smckusick
53535500Sbostic case unary_op: /* this could be any unary operation */
53635500Sbostic if (ps.want_blank)
53735500Sbostic *e_code++ = ' ';
5388800Smckusick
53935500Sbostic if (troff && !ps.dumped_decl_indent && ps.in_decl && !is_procname) {
54035500Sbostic sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token);
54135500Sbostic ps.dumped_decl_indent = 1;
54235500Sbostic e_code += strlen(e_code);
54335500Sbostic }
54435500Sbostic else {
54535500Sbostic char *res = token;
54624453Smckusick
54735500Sbostic if (ps.in_decl && !ps.block_init) { /* if this is a unary op
54824453Smckusick * in a declaration, we
54924453Smckusick * should indent this
55024453Smckusick * token */
55135500Sbostic for (i = 0; token[i]; ++i); /* find length of token */
55235500Sbostic while ((e_code - s_code) < (dec_ind - i)) {
55340275Sbostic CHECK_SIZE_CODE;
55435500Sbostic *e_code++ = ' '; /* pad it */
55524453Smckusick }
5568800Smckusick }
55735500Sbostic if (troff && token[0] == '-' && token[1] == '>')
55835500Sbostic res = "\\(->";
55935500Sbostic for (t_ptr = res; *t_ptr; ++t_ptr) {
56040275Sbostic CHECK_SIZE_CODE;
56135500Sbostic *e_code++ = *t_ptr;
56235500Sbostic }
56335500Sbostic }
56435500Sbostic ps.want_blank = false;
56535500Sbostic break;
5668800Smckusick
56735500Sbostic case binary_op: /* any binary operation */
56835500Sbostic if (ps.want_blank)
56935500Sbostic *e_code++ = ' ';
57035500Sbostic {
57135500Sbostic char *res = token;
57224453Smckusick
57335500Sbostic if (troff)
57435500Sbostic switch (token[0]) {
57535500Sbostic case '<':
57635500Sbostic if (token[1] == '=')
57735500Sbostic res = "\\(<=";
57835500Sbostic break;
57935500Sbostic case '>':
58035500Sbostic if (token[1] == '=')
58135500Sbostic res = "\\(>=";
58235500Sbostic break;
58335500Sbostic case '!':
58435500Sbostic if (token[1] == '=')
58535500Sbostic res = "\\(!=";
58635500Sbostic break;
58735500Sbostic case '|':
58835500Sbostic if (token[1] == '|')
58935500Sbostic res = "\\(br\\(br";
59035500Sbostic else if (token[1] == 0)
59135500Sbostic res = "\\(br";
59235500Sbostic break;
59335500Sbostic }
59435500Sbostic for (t_ptr = res; *t_ptr; ++t_ptr) {
59540275Sbostic CHECK_SIZE_CODE;
59635500Sbostic *e_code++ = *t_ptr; /* move the operator */
59724453Smckusick }
59835500Sbostic }
59935500Sbostic ps.want_blank = true;
60035500Sbostic break;
6018800Smckusick
60235500Sbostic case postop: /* got a trailing ++ or -- */
60335500Sbostic *e_code++ = token[0];
60435500Sbostic *e_code++ = token[1];
60535500Sbostic ps.want_blank = true;
60635500Sbostic break;
6078800Smckusick
60835500Sbostic case question: /* got a ? */
60935500Sbostic squest++; /* this will be used when a later colon
61024453Smckusick * appears so we can distinguish the
61124453Smckusick * <c>?<n>:<n> construct */
61235500Sbostic if (ps.want_blank)
61335500Sbostic *e_code++ = ' ';
61435500Sbostic *e_code++ = '?';
61535500Sbostic ps.want_blank = true;
61635500Sbostic break;
61735500Sbostic
61835500Sbostic case casestmt: /* got word 'case' or 'default' */
61935500Sbostic scase = true; /* so we can process the later colon properly */
62035500Sbostic goto copy_id;
62135500Sbostic
62235500Sbostic case colon: /* got a ':' */
62335500Sbostic if (squest > 0) { /* it is part of the <c>?<n>: <n> construct */
62435500Sbostic --squest;
62524453Smckusick if (ps.want_blank)
6268800Smckusick *e_code++ = ' ';
62735500Sbostic *e_code++ = ':';
62824453Smckusick ps.want_blank = true;
6298800Smckusick break;
63035500Sbostic }
63135500Sbostic if (ps.in_decl) {
63235500Sbostic *e_code++ = ':';
63324453Smckusick ps.want_blank = false;
6348800Smckusick break;
63535500Sbostic }
63635500Sbostic ps.in_stmt = false; /* seeing a label does not imply we are in a
63735500Sbostic * stmt */
63835500Sbostic for (t_ptr = s_code; *t_ptr; ++t_ptr)
63935500Sbostic *e_lab++ = *t_ptr; /* turn everything so far into a label */
64035500Sbostic e_code = s_code;
64135500Sbostic *e_lab++ = ':';
64235500Sbostic *e_lab++ = ' ';
64335500Sbostic *e_lab = '\0';
6448800Smckusick
64535500Sbostic force_nl = ps.pcase = scase; /* ps.pcase will be used by
64635500Sbostic * dump_line to decide how to
64735500Sbostic * indent the label. force_nl
64835500Sbostic * will force a case n: to be
64935500Sbostic * on a line by itself */
65035500Sbostic scase = false;
65135500Sbostic ps.want_blank = false;
65235500Sbostic break;
6538800Smckusick
65435500Sbostic case semicolon: /* got a ';' */
65535500Sbostic ps.in_or_st = false;/* we are not in an initialization or
65635500Sbostic * structure declaration */
65735500Sbostic scase = false; /* these will only need resetting in a error */
65835500Sbostic squest = 0;
65938011Sbostic if (ps.last_token == rparen && rparen_count == 0)
66035500Sbostic ps.in_parameter_declaration = 0;
66135500Sbostic ps.cast_mask = 0;
66235500Sbostic ps.sizeof_mask = 0;
66335500Sbostic ps.block_init = 0;
66435500Sbostic ps.block_init_level = 0;
66535500Sbostic ps.just_saw_decl--;
6668800Smckusick
66735500Sbostic if (ps.in_decl && s_code == e_code && !ps.block_init)
66835500Sbostic while ((e_code - s_code) < (dec_ind - 1)) {
66940275Sbostic CHECK_SIZE_CODE;
67035500Sbostic *e_code++ = ' ';
67135500Sbostic }
6728800Smckusick
67335500Sbostic ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level
67435500Sbostic * structure declaration, we
67535500Sbostic * arent any more */
67624453Smckusick
67735500Sbostic if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) {
6788800Smckusick
67935500Sbostic /*
68035500Sbostic * This should be true iff there were unbalanced parens in the
68135500Sbostic * stmt. It is a bit complicated, because the semicolon might
68235500Sbostic * be in a for stmt
68335500Sbostic */
68435500Sbostic diag(1, "Unbalanced parens");
68535500Sbostic ps.p_l_follow = 0;
68635500Sbostic if (sp_sw) { /* this is a check for a if, while, etc. with
68735500Sbostic * unbalanced parens */
68835500Sbostic sp_sw = false;
68935500Sbostic parse(hd_type); /* dont lose the if, or whatever */
6908800Smckusick }
69135500Sbostic }
69235500Sbostic *e_code++ = ';';
69335500Sbostic ps.want_blank = true;
69435500Sbostic ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the
69535500Sbostic * middle of a stmt */
6968800Smckusick
69735500Sbostic if (!sp_sw) { /* if not if for (;;) */
69835500Sbostic parse(semicolon); /* let parser know about end of stmt */
69935500Sbostic force_nl = true;/* force newline after a end of stmt */
70035500Sbostic }
70135500Sbostic break;
7028800Smckusick
70335500Sbostic case lbrace: /* got a '{' */
70435500Sbostic ps.in_stmt = false; /* dont indent the {} */
70535500Sbostic if (!ps.block_init)
70635500Sbostic force_nl = true;/* force other stuff on same line as '{' onto
70735500Sbostic * new line */
70835500Sbostic else if (ps.block_init_level <= 0)
70935500Sbostic ps.block_init_level = 1;
71035500Sbostic else
71135500Sbostic ps.block_init_level++;
7128800Smckusick
71335500Sbostic if (s_code != e_code && !ps.block_init) {
71435500Sbostic if (!btype_2) {
71535500Sbostic dump_line();
71635500Sbostic ps.want_blank = false;
7178800Smckusick }
71835500Sbostic else if (ps.in_parameter_declaration && !ps.in_or_st) {
71935500Sbostic ps.i_l_follow = 0;
72035500Sbostic dump_line();
72135500Sbostic ps.want_blank = false;
7228800Smckusick }
72335500Sbostic }
72435500Sbostic if (ps.in_parameter_declaration)
72535500Sbostic prefix_blankline_requested = 0;
7268800Smckusick
72735500Sbostic if (ps.p_l_follow > 0) { /* check for preceeding unbalanced
72835500Sbostic * parens */
72935500Sbostic diag(1, "Unbalanced parens");
73035500Sbostic ps.p_l_follow = 0;
73135500Sbostic if (sp_sw) { /* check for unclosed if, for, etc. */
7328800Smckusick sp_sw = false;
73335500Sbostic parse(hd_type);
73435500Sbostic ps.ind_level = ps.i_l_follow;
7358800Smckusick }
73635500Sbostic }
73735500Sbostic if (s_code == e_code)
73835500Sbostic ps.ind_stmt = false; /* dont put extra indentation on line
73935500Sbostic * with '{' */
74035500Sbostic if (ps.in_decl && ps.in_or_st) { /* this is either a structure
74135500Sbostic * declaration or an init */
74235500Sbostic di_stack[ps.dec_nest++] = dec_ind;
74335500Sbostic /* ? dec_ind = 0; */
74435500Sbostic }
74535500Sbostic else {
74635500Sbostic ps.decl_on_line = false; /* we cant be in the middle of
74735500Sbostic * a declaration, so dont do
74835500Sbostic * special indentation of
74935500Sbostic * comments */
75035500Sbostic if (blanklines_after_declarations_at_proctop
75135500Sbostic && ps.in_parameter_declaration)
75224453Smckusick postfix_blankline_requested = 1;
75335500Sbostic ps.in_parameter_declaration = 0;
75435500Sbostic }
75535500Sbostic dec_ind = 0;
75635500Sbostic parse(lbrace); /* let parser know about this */
75735500Sbostic if (ps.want_blank) /* put a blank before '{' if '{' is not at
75835500Sbostic * start of line */
75935500Sbostic *e_code++ = ' ';
76035500Sbostic ps.want_blank = false;
76135500Sbostic *e_code++ = '{';
76235500Sbostic ps.just_saw_decl = 0;
76335500Sbostic break;
7648800Smckusick
76535500Sbostic case rbrace: /* got a '}' */
76635500Sbostic if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be
76735500Sbostic * omitted in
76835500Sbostic * declarations */
76935500Sbostic parse(semicolon);
77035500Sbostic if (ps.p_l_follow) {/* check for unclosed if, for, else. */
77135500Sbostic diag(1, "Unbalanced parens");
77235500Sbostic ps.p_l_follow = 0;
77335500Sbostic sp_sw = false;
77435500Sbostic }
77535500Sbostic ps.just_saw_decl = 0;
77635500Sbostic ps.block_init_level--;
77735500Sbostic if (s_code != e_code && !ps.block_init) { /* '}' must be first on
77835500Sbostic * line */
77935500Sbostic if (verbose)
78035500Sbostic diag(0, "Line broken");
78135500Sbostic dump_line();
78235500Sbostic }
78335500Sbostic *e_code++ = '}';
78435500Sbostic ps.want_blank = true;
78535500Sbostic ps.in_stmt = ps.ind_stmt = false;
78635500Sbostic if (ps.dec_nest > 0) { /* we are in multi-level structure
78735500Sbostic * declaration */
78835500Sbostic dec_ind = di_stack[--ps.dec_nest];
78935500Sbostic if (ps.dec_nest == 0 && !ps.in_parameter_declaration)
79035500Sbostic ps.just_saw_decl = 2;
79135500Sbostic ps.in_decl = true;
79235500Sbostic }
79335500Sbostic prefix_blankline_requested = 0;
79435500Sbostic parse(rbrace); /* let parser know about this */
79535500Sbostic ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead
79635500Sbostic && ps.il[ps.tos] >= ps.ind_level;
79735500Sbostic if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0)
79835500Sbostic postfix_blankline_requested = 1;
79935500Sbostic break;
8008800Smckusick
80135500Sbostic case swstmt: /* got keyword "switch" */
80235500Sbostic sp_sw = true;
80335500Sbostic hd_type = swstmt; /* keep this for when we have seen the
80435500Sbostic * expression */
80535500Sbostic goto copy_id; /* go move the token into buffer */
80635500Sbostic
80735500Sbostic case sp_paren: /* token is if, while, for */
80835500Sbostic sp_sw = true; /* the interesting stuff is done after the
80924453Smckusick * expression is scanned */
81035500Sbostic hd_type = (*token == 'i' ? ifstmt :
81135500Sbostic (*token == 'w' ? whilestmt : forstmt));
8128800Smckusick
81335500Sbostic /*
81435500Sbostic * remember the type of header for later use by parser
81535500Sbostic */
81635500Sbostic goto copy_id; /* copy the token into line */
81724453Smckusick
81835500Sbostic case sp_nparen: /* got else, do */
81935500Sbostic ps.in_stmt = false;
82035500Sbostic if (*token == 'e') {
82135500Sbostic if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) {
82235500Sbostic if (verbose)
82335500Sbostic diag(0, "Line broken");
82435500Sbostic dump_line();/* make sure this starts a line */
82535500Sbostic ps.want_blank = false;
8268800Smckusick }
82735500Sbostic force_nl = true;/* also, following stuff must go onto new line */
82835500Sbostic last_else = 1;
82935500Sbostic parse(elselit);
83035500Sbostic }
83135500Sbostic else {
83235500Sbostic if (e_code != s_code) { /* make sure this starts a line */
83335500Sbostic if (verbose)
83435500Sbostic diag(0, "Line broken");
83535500Sbostic dump_line();
83635500Sbostic ps.want_blank = false;
83735500Sbostic }
83835500Sbostic force_nl = true;/* also, following stuff must go onto new line */
83935500Sbostic last_else = 0;
84035500Sbostic parse(dolit);
84135500Sbostic }
84235500Sbostic goto copy_id; /* move the token into line */
8438800Smckusick
84435500Sbostic case decl: /* we have a declaration type (int, register,
84535500Sbostic * etc.) */
84635500Sbostic parse(decl); /* let parser worry about indentation */
84735500Sbostic if (ps.last_token == rparen && ps.tos <= 1) {
84835500Sbostic ps.in_parameter_declaration = 1;
84935500Sbostic if (s_code != e_code) {
85035500Sbostic dump_line();
85135500Sbostic ps.want_blank = 0;
85224453Smckusick }
85335500Sbostic }
85435500Sbostic if (ps.in_parameter_declaration && ps.indent_parameters && ps.dec_nest == 0) {
85535500Sbostic ps.ind_level = ps.i_l_follow = 1;
85635500Sbostic ps.ind_stmt = 0;
85735500Sbostic }
85835500Sbostic ps.in_or_st = true; /* this might be a structure or initialization
85935500Sbostic * declaration */
86035500Sbostic ps.in_decl = ps.decl_on_line = true;
86135500Sbostic if ( /* !ps.in_or_st && */ ps.dec_nest <= 0)
86235500Sbostic ps.just_saw_decl = 2;
86335500Sbostic prefix_blankline_requested = 0;
86435500Sbostic for (i = 0; token[i++];); /* get length of token */
8658800Smckusick
86635500Sbostic /*
86735500Sbostic * dec_ind = e_code - s_code + (ps.decl_indent>i ? ps.decl_indent
86835500Sbostic * : i);
86935500Sbostic */
87035500Sbostic dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i;
87135500Sbostic goto copy_id;
8728800Smckusick
87335500Sbostic case ident: /* got an identifier or constant */
87435500Sbostic if (ps.in_decl) { /* if we are in a declaration, we must indent
87535500Sbostic * identifier */
87624453Smckusick if (ps.want_blank)
8778800Smckusick *e_code++ = ' ';
87835500Sbostic ps.want_blank = false;
87935500Sbostic if (is_procname == 0 || !procnames_start_line) {
88035500Sbostic if (!ps.block_init)
88135500Sbostic if (troff && !ps.dumped_decl_indent) {
88235500Sbostic sprintf(e_code, "\n.De %dp+\200p\n", dec_ind * 7);
88335500Sbostic ps.dumped_decl_indent = 1;
88435500Sbostic e_code += strlen(e_code);
88535500Sbostic }
88635500Sbostic else
88735500Sbostic while ((e_code - s_code) < dec_ind) {
88840275Sbostic CHECK_SIZE_CODE;
88935500Sbostic *e_code++ = ' ';
89035500Sbostic }
89124453Smckusick }
89235500Sbostic else {
89335500Sbostic if (dec_ind && s_code != e_code)
89435500Sbostic dump_line();
89535500Sbostic dec_ind = 0;
89635500Sbostic ps.want_blank = false;
89735500Sbostic }
89835500Sbostic }
89935500Sbostic else if (sp_sw && ps.p_l_follow == 0) {
90035500Sbostic sp_sw = false;
90135500Sbostic force_nl = true;
90235500Sbostic ps.last_u_d = true;
90335500Sbostic ps.in_stmt = false;
90435500Sbostic parse(hd_type);
90535500Sbostic }
90635500Sbostic copy_id:
90735500Sbostic if (ps.want_blank)
90835500Sbostic *e_code++ = ' ';
90935500Sbostic if (troff && ps.its_a_keyword) {
91035500Sbostic e_code = chfont(&bodyf, &keywordf, e_code);
91135500Sbostic for (t_ptr = token; *t_ptr; ++t_ptr) {
91240275Sbostic CHECK_SIZE_CODE;
91335500Sbostic *e_code++ = keywordf.allcaps && islower(*t_ptr)
91435500Sbostic ? toupper(*t_ptr) : *t_ptr;
91535500Sbostic }
91635500Sbostic e_code = chfont(&keywordf, &bodyf, e_code);
91735500Sbostic }
91835500Sbostic else
91935500Sbostic for (t_ptr = token; *t_ptr; ++t_ptr) {
92040275Sbostic CHECK_SIZE_CODE;
9218800Smckusick *e_code++ = *t_ptr;
92224453Smckusick }
92335500Sbostic ps.want_blank = true;
92435500Sbostic break;
9258800Smckusick
92635500Sbostic case period: /* treat a period kind of like a binary
92724453Smckusick * operation */
92835500Sbostic *e_code++ = '.'; /* move the period into line */
92935500Sbostic ps.want_blank = false; /* dont put a blank after a period */
93035500Sbostic break;
9318800Smckusick
93235500Sbostic case comma:
93335500Sbostic ps.want_blank = (s_code != e_code); /* only put blank after comma
93435500Sbostic * if comma does not start the
93535500Sbostic * line */
93635500Sbostic if (ps.in_decl && is_procname == 0 && !ps.block_init)
93735500Sbostic while ((e_code - s_code) < (dec_ind - 1)) {
93840275Sbostic CHECK_SIZE_CODE;
93935500Sbostic *e_code++ = ' ';
94035500Sbostic }
9418800Smckusick
94235500Sbostic *e_code++ = ',';
94335500Sbostic if (ps.p_l_follow == 0) {
94435500Sbostic if (ps.block_init_level <= 0)
94524453Smckusick ps.block_init = 0;
94638011Sbostic if (break_comma && (!ps.leave_comma || compute_code_target() + (e_code - s_code) > max_col - 8))
94735500Sbostic force_nl = true;
94835500Sbostic }
94935500Sbostic break;
9508800Smckusick
95135500Sbostic case preesc: /* got the character '#' */
95235500Sbostic if ((s_com != e_com) ||
95324453Smckusick (s_lab != e_lab) ||
95424453Smckusick (s_code != e_code))
95535500Sbostic dump_line();
95635500Sbostic *e_lab++ = '#'; /* move whole line to 'label' buffer */
95735500Sbostic {
95835500Sbostic int in_comment = 0;
95935500Sbostic int com_start = 0;
96035500Sbostic char quote = 0;
96135500Sbostic int com_end = 0;
9628800Smckusick
96338011Sbostic while (*buf_ptr == ' ' || *buf_ptr == '\t') {
96438011Sbostic buf_ptr++;
96538011Sbostic if (buf_ptr >= buf_end)
96638011Sbostic fill_buffer();
96738011Sbostic }
96835500Sbostic while (*buf_ptr != '\n' || in_comment) {
96940275Sbostic CHECK_SIZE_LAB;
97035500Sbostic *e_lab = *buf_ptr++;
97135500Sbostic if (buf_ptr >= buf_end)
97235500Sbostic fill_buffer();
97335500Sbostic switch (*e_lab++) {
97435500Sbostic case BACKSLASH:
97535500Sbostic if (troff)
97635500Sbostic *e_lab++ = BACKSLASH;
97735500Sbostic if (!in_comment) {
97835500Sbostic *e_lab++ = *buf_ptr++;
97935500Sbostic if (buf_ptr >= buf_end)
98035500Sbostic fill_buffer();
98124453Smckusick }
98235500Sbostic break;
98335500Sbostic case '/':
98435500Sbostic if (*buf_ptr == '*' && !in_comment && !quote) {
98535500Sbostic in_comment = 1;
98635500Sbostic *e_lab++ = *buf_ptr++;
98735500Sbostic com_start = e_lab - s_lab - 2;
98835500Sbostic }
98935500Sbostic break;
99035500Sbostic case '"':
99135500Sbostic if (quote == '"')
99235500Sbostic quote = 0;
99335500Sbostic break;
99435500Sbostic case '\'':
99535500Sbostic if (quote == '\'')
99635500Sbostic quote = 0;
99735500Sbostic break;
99835500Sbostic case '*':
99935500Sbostic if (*buf_ptr == '/' && in_comment) {
100035500Sbostic in_comment = 0;
100135500Sbostic *e_lab++ = *buf_ptr++;
100235500Sbostic com_end = e_lab - s_lab;
100335500Sbostic }
100435500Sbostic break;
10058800Smckusick }
100635500Sbostic }
100735500Sbostic
100835500Sbostic while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
100935500Sbostic e_lab--;
101035500Sbostic if (e_lab - s_lab == com_end && bp_save == 0) { /* comment on
101124453Smckusick * preprocessor line */
101235500Sbostic if (sc_end == 0) /* if this is the first comment, we
101335500Sbostic * must set up the buffer */
101435500Sbostic sc_end = &(save_com[0]);
101535500Sbostic else {
101635500Sbostic *sc_end++ = '\n'; /* add newline between
101724453Smckusick * comments */
101835500Sbostic *sc_end++ = ' ';
101935500Sbostic --line_no;
102024453Smckusick }
102135500Sbostic bcopy(s_lab + com_start, sc_end, com_end - com_start);
102235500Sbostic sc_end += com_end - com_start;
102335500Sbostic if (sc_end >= &save_com[sc_size])
102435500Sbostic abort();
102535500Sbostic e_lab = s_lab + com_start;
102635500Sbostic while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
102735500Sbostic e_lab--;
102835500Sbostic bp_save = buf_ptr; /* save current input buffer */
102935500Sbostic be_save = buf_end;
103035500Sbostic buf_ptr = save_com; /* fix so that subsequent calls to
103135500Sbostic * lexi will take tokens out of
103235500Sbostic * save_com */
103335500Sbostic *sc_end++ = ' '; /* add trailing blank, just in case */
103435500Sbostic buf_end = sc_end;
103535500Sbostic sc_end = 0;
10368800Smckusick }
103735500Sbostic *e_lab = '\0'; /* null terminate line */
103835500Sbostic ps.pcase = false;
103935500Sbostic }
104035500Sbostic
104135500Sbostic if (strncmp(s_lab, "#if", 3) == 0) {
104235500Sbostic if (blanklines_around_conditional_compilation) {
104335500Sbostic register c;
104435500Sbostic prefix_blankline_requested++;
104535500Sbostic while ((c = getc(input)) == '\n');
104635500Sbostic ungetc(c, input);
104735500Sbostic }
104835500Sbostic if (ifdef_level < sizeof state_stack / sizeof state_stack[0]) {
104935500Sbostic match_state[ifdef_level].tos = -1;
105035500Sbostic state_stack[ifdef_level++] = ps;
105135500Sbostic }
105235500Sbostic else
105335500Sbostic diag(1, "#if stack overflow");
105435500Sbostic }
105535500Sbostic else if (strncmp(s_lab, "#else", 5) == 0)
105635500Sbostic if (ifdef_level <= 0)
105735500Sbostic diag(1, "Unmatched #else");
105835500Sbostic else {
105935500Sbostic match_state[ifdef_level - 1] = ps;
106035500Sbostic ps = state_stack[ifdef_level - 1];
106135500Sbostic }
106235500Sbostic else if (strncmp(s_lab, "#endif", 6) == 0) {
106335500Sbostic if (ifdef_level <= 0)
106435500Sbostic diag(1, "Unmatched #endif");
106535500Sbostic else {
106635500Sbostic ifdef_level--;
106735500Sbostic
106824453Smckusick #ifdef undef
106935500Sbostic /*
107035500Sbostic * This match needs to be more intelligent before the
107135500Sbostic * message is useful
107235500Sbostic */
107335500Sbostic if (match_state[ifdef_level].tos >= 0
107435500Sbostic && bcmp(&ps, &match_state[ifdef_level], sizeof ps))
107535500Sbostic diag(0, "Syntactically inconsistant #ifdef alternatives.");
107624453Smckusick #endif
107735500Sbostic }
107835500Sbostic if (blanklines_around_conditional_compilation) {
107935500Sbostic postfix_blankline_requested++;
108035500Sbostic n_real_blanklines = 0;
108135500Sbostic }
108235500Sbostic }
108335500Sbostic break; /* subsequent processing of the newline
108435500Sbostic * character will cause the line to be printed */
10858800Smckusick
108635500Sbostic case comment: /* we have gotten a /* this is a biggie */
108735500Sbostic if (flushed_nl) { /* we should force a broken line here */
108835500Sbostic flushed_nl = false;
108935500Sbostic dump_line();
109035500Sbostic ps.want_blank = false; /* dont insert blank at line start */
109135500Sbostic force_nl = false;
109235500Sbostic }
109335500Sbostic pr_comment();
109435500Sbostic break;
109524453Smckusick } /* end of big switch stmt */
109635500Sbostic
109735500Sbostic *e_code = '\0'; /* make sure code section is null terminated */
109824453Smckusick if (type_code != comment && type_code != newline && type_code != preesc)
109924453Smckusick ps.last_token = type_code;
110024453Smckusick } /* end of main while (1) loop */
110136970Sbostic }
11028800Smckusick
11038800Smckusick /*
110435500Sbostic * copy input file to backup file if in_name is /blah/blah/blah/file, then
110535500Sbostic * backup file will be ".Bfile" then make the backup file the input and
110635500Sbostic * original input file the output
11078800Smckusick */
bakcopy()110824453Smckusick bakcopy()
110924453Smckusick {
111024453Smckusick int n,
111124453Smckusick bakchn;
111235500Sbostic char buff[8 * 1024];
111324453Smckusick register char *p;
11148800Smckusick
111535500Sbostic /* construct file name .Bfile */
111635500Sbostic for (p = in_name; *p; p++); /* skip to end of string */
111735500Sbostic while (p > in_name && *p != '/') /* find last '/' */
111835500Sbostic p--;
111935500Sbostic if (*p == '/')
11208800Smckusick p++;
112124453Smckusick sprintf(bakfile, "%s.BAK", p);
11228800Smckusick
112324453Smckusick /* copy in_name to backup file */
112424453Smckusick bakchn = creat(bakfile, 0600);
112536970Sbostic if (bakchn < 0)
112636970Sbostic err(bakfile);
112735500Sbostic while (n = read(fileno(input), buff, sizeof buff))
112836970Sbostic if (write(bakchn, buff, n) != n)
112936970Sbostic err(bakfile);
113036970Sbostic if (n < 0)
113136970Sbostic err(in_name);
113224453Smckusick close(bakchn);
113324453Smckusick fclose(input);
11348800Smckusick
113524453Smckusick /* re-open backup file as the input file */
113624453Smckusick input = fopen(bakfile, "r");
113736970Sbostic if (input == 0)
113836970Sbostic err(bakfile);
113924453Smckusick /* now the original input file will be the output */
114024453Smckusick output = fopen(in_name, "w");
114135500Sbostic if (output == 0) {
114224453Smckusick unlink(bakfile);
114336970Sbostic err(in_name);
11448800Smckusick }
11458800Smckusick }
114636970Sbostic
err(msg)114736970Sbostic err(msg)
114836970Sbostic char *msg;
114936970Sbostic {
115036970Sbostic extern int errno;
115136970Sbostic char *strerror();
115236970Sbostic
115336970Sbostic (void)fprintf(stderr, "indent: %s: %s\n", msg, strerror(errno));
115436970Sbostic exit(1);
115536970Sbostic }
1156