home *** CD-ROM | disk | FTP | other *** search
- #include "indent_globs.h"
-
- struct parser_state match_state[STACK_SIZE];
- struct parser_state state_stack[STACK_SIZE];
-
- extern int dec_ind; /* current indentation for declarations */
- extern int di_stack[STACKS]; /* a stack of structure indentation levels */
- extern int flushed_nl; /* used when buffering up comments to
- * remember that a newline was passed over */
- extern int force_nl; /* when true, code must be broken */
- extern int hd_type; /* used to store type of stmt for if (...),
- * for (...), etc */
- extern int scase; /* set to true when we see a case, so we will
- * know what to do with the following colon */
- extern int sp_sw; /* when true, we are in the expressin of
- * if(...), while(...), etc. */
- extern int squest; /* when this is positive, we have seen a ?
- * without the matching : in a <c>?<s>:<s>
- * construct */
- extern int type_code; /* the type of token, returned by lexi */
-
- extern int last_else; /* true iff last keyword was an else */
-
- extern int is_procname;
-
-
- void switch_on(type_code)
- int type_code;
- {
- register int i;
- register char *t_ptr; /* used for copying tokens */
-
-
- /*----------------------------------------------------*\
- | do switch on type of token scanned
- \*----------------------------------------------------*/
- switch (type_code) { /* now, decide what to do with the token */
-
- case form_feed: /* found a form feed in line */
- ps.use_ff = true; /* a form feed is treated much like a newline */
- dump_line();
- ps.want_blank = false;
- break;
-
- case newline:
- if (ps.last_token != comma || ps.p_l_follow > 0
- || !ps.leave_comma || !break_comma || s_com != e_com) {
- dump_line();
- ps.want_blank = false;
- }
- ++line_no; /* keep track of input line number */
- break;
-
- case lparen: /* got a '(' or '[' */
- ++ps.p_l_follow; /* count parens to make Healy happy */
- if (ps.want_blank && *token != '[' &&
- (ps.last_token != ident || proc_calls_space
- || (ps.its_a_keyword && !ps.sizeof_keyword)))
- *e_code++ = ' ';
- if (ps.in_decl && !ps.block_init)
- if (troff && !ps.dumped_decl_indent) {
- ps.dumped_decl_indent = 1;
- sprintf(e_code, "\\c\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token);
- e_code += strlen(e_code);
- } else {
- while ((e_code - s_code) < dec_ind)
- *e_code++ = ' ';
- *e_code++ = token[0];
- }
- else
- *e_code++ = token[0];
- ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code;
- ps.want_blank = false;
- if (ps.in_or_st && *token == '(') {
-
- /* this is a kluge to make sure that declarations will be
- * aligned right if proc decl has an explicit type on it,
- * i.e. "int a(x) {..." */
- parse(semicolon); /* I said this was a kluge... */
- ps.in_or_st = false; /* turn off flag for structure decl
- * or initialization */
- }
- if (ps.sizeof_keyword)
- ps.sizeof_mask |= 1 << ps.p_l_follow;
- break;
-
- case rparen: /* got a ')' or ']' */
- if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask) {
- ps.last_u_d = true;
- ps.cast_mask &= (1 << ps.p_l_follow) - 1;
- }
- ps.sizeof_mask &= (1 << ps.p_l_follow) - 1;
- if (--ps.p_l_follow < 0) {
- ps.p_l_follow = 0;
- diag(0, "Extra %c", *token);
- }
- if (e_code == s_code) /* if the paren starts the line */
- ps.paren_level = ps.p_l_follow; /* then indent it */
-
- *e_code++ = token[0];
- ps.want_blank = true;
-
- if (sp_sw && (ps.p_l_follow == 0)) { /* check for end of if
- * (...), or some such */
- sp_sw = false;
- force_nl = true;/* must force newline after if */
- ps.last_u_d = true; /* inform lexi that a following
- * operator is unary */
- ps.in_stmt = false; /* dont use stmt continuation
- * indentation */
-
- parse(hd_type); /* let parser worry about if, or whatever */
- }
- ps.search_brace = btype_2; /* this should insure that constructs
- * such as main(){...} and int[]{...}
- * have their braces put in the right
- * place */
- break;
-
- case unary_op: /* this could be any unary operation */
- if (ps.want_blank)
- *e_code++ = ' ';
-
- if (troff && !ps.dumped_decl_indent && ps.in_decl) {
- sprintf(e_code, "\\c\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token);
- ps.dumped_decl_indent = 1;
- e_code += strlen(e_code);
- } else {
- char *res = token;
-
- if (ps.in_decl && !ps.block_init) { /* if this is a unary op
- * in a declaration, we
- * should indent this
- * token */
- for (i = 0; token[i]; ++i); /* find length of token */
- while ((e_code - s_code) < (dec_ind - i))
- *e_code++ = ' '; /* pad it */
- }
- if (troff && token[0] == '-' && token[1] == '>')
- res = "\\(->";
- for (t_ptr = res; *t_ptr; ++t_ptr)
- *e_code++ = *t_ptr;
- }
- ps.want_blank = false;
- break;
-
- case binary_op: /* any binary operation */
- do_binary:
- if (ps.want_blank)
- *e_code++ = ' ';
- {
- char *res = token;
-
- if (troff)
- switch (token[0]) {
- case '<':
- if (token[1] == '=')
- res = "\\(<=";
- break;
- case '>':
- if (token[1] == '=')
- res = "\\(>=";
- break;
- case '!':
- if (token[1] == '=')
- res = "\\(!=";
- break;
- case '|':
- if (token[1] == '|')
- res = "\\(br\\(br";
- else if (token[1] == 0)
- res = "\\(br";
- break;
- case '-':
- if (token[1] == '>')
- res = "\\(->";
- }
- for (t_ptr = res; *t_ptr; ++t_ptr)
- *e_code++ = *t_ptr; /* move the operator */
- }
- ps.want_blank = true;
- break;
-
- case postop: /* got a trailing ++ or -- */
- *e_code++ = token[0];
- *e_code++ = token[1];
- ps.want_blank = true;
- break;
-
- case question: /* got a ? */
- squest++; /* this will be used when a later colon
- * appears so we can distinguish the
- * <c>?<n>:<n> construct */
- if (ps.want_blank)
- *e_code++ = ' ';
- *e_code++ = '?';
- ps.want_blank = true;
- break;
-
- case casestmt: /* got word 'case' or 'default' */
- scase = true; /* so we can process the later colon properly */
- goto copy_id;
-
- case colon: /* got a ':' */
- if (squest > 0) { /* it is part of the <c>?<n>: <n> construct */
- --squest;
- if (ps.want_blank)
- *e_code++ = ' ';
- *e_code++ = ':';
- ps.want_blank = true;
- break;
- }
- if (ps.in_decl) {
- *e_code++ = ':';
- ps.want_blank = false;
- break;
- }
- ps.in_stmt = false; /* seeing a label does not imply we are in a
- * stmt */
- for (t_ptr = s_code; *t_ptr; ++t_ptr)
- *e_lab++ = *t_ptr; /* turn everything so far into a
- * label */
- e_code = s_code;
- *e_lab++ = ':';
- *e_lab++ = ' ';
- *e_lab = '\0';
-
- force_nl = ps.pcase = scase; /* ps.pcase will be used by
- * dump_line to decide how to
- * indent the label. force_nl
- * will force a case n: to be
- * on a line by itself */
- scase = false;
- ps.want_blank = false;
- break;
-
- case semicolon: /* got a ';' */
- ps.in_or_st = false;/* we are not in an initialization or
- * structure declaration */
- scase = false; /* these will only need resetting in a error */
- squest = 0;
- if (ps.last_token == rparen)
- ps.in_parameter_declaration = 0;
- ps.cast_mask = 0;
- ps.sizeof_mask = 0;
- ps.block_init = 0;
- ps.just_saw_decl--;
-
- if (ps.in_decl && s_code == e_code && !ps.block_init)
- while ((e_code - s_code) < (dec_ind - 1))
- *e_code++ = ' ';
-
- ps.in_decl = (ps.dec_nest > 0); /* if we were in a first
- * level structure
- * declaration, we arent any
- * more */
-
- if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) {
-
- /* This should be true iff there were unbalanced parens in
- * the stmt. It is a bit complicated, because the semicolon
- * might be in a for stmt */
- diag(1, "Unbalanced parens");
- ps.p_l_follow = 0;
- if (sp_sw) { /* this is a check for a if, while, etc. with
- * unbalanced parens */
- sp_sw = false;
- parse(hd_type); /* dont lose the if, or whatever */
- }
- }
- *e_code++ = ';';
- ps.want_blank = true;
- ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the
- * middle of a stmt */
-
- if (!sp_sw) { /* if not if for (;;) */
- parse(semicolon); /* let parser know about end of stmt */
- force_nl = true;/* force newline after a end of stmt */
- }
- break;
-
- case lbrace: /* got a 'lbrace' */
- ps.in_stmt = false; /* dont indent the {} */
- if (!ps.block_init)
- force_nl = true;/* force other stuff on same line as 'lbrace'
- * onto new line */
-
- if (s_code != e_code && !ps.block_init) {
- if (!btype_2) {
- dump_line();
- ps.want_blank = false;
- } else if (ps.in_parameter_declaration && !ps.in_or_st) {
- ps.i_l_follow = 0;
- dump_line();
- ps.want_blank = false;
- }
- }
- if (ps.in_parameter_declaration)
- prefix_blankline_requested = 0;
-
- if (ps.p_l_follow > 0) { /* check for preceding unbalanced
- * parens */
- diag(1, "Unbalanced parens");
- ps.p_l_follow = 0;
- if (sp_sw) { /* check for unclosed if, for, etc. */
- sp_sw = false;
- parse(hd_type);
- ps.ind_level = ps.i_l_follow;
- }
- }
- if (s_code == e_code)
- ps.ind_stmt = false; /* dont put extra indentation on line
- * with '{' */
- if (ps.in_decl && ps.in_or_st) { /* this is either a structure
- * declaration or an init */
- di_stack[ps.dec_nest++] = dec_ind;
- dec_ind = 0;
- } else {
- ps.decl_on_line = false; /* we cant be in the middle
- * of a declaration, so dont
- * do special indentation of
- * comments */
- ps.in_parameter_declaration = 0;
- }
- parse(lbrace); /* let parser know about this */
- if (ps.want_blank) /* put a blank before '{' if '{' is not at
- * start of line */
- *e_code++ = ' ';
- ps.want_blank = false;
- *e_code++ = '{';
- ps.just_saw_decl = 0;
- break;
-
- case rbrace: /* got a '}' */
- if (ps.p_l_follow) {/* check for unclosed if, for, else. */
- diag(1, "Unbalanced parens");
- ps.p_l_follow = 0;
- sp_sw = false;
- }
- ps.just_saw_decl = 0;
- if (s_code != e_code && !ps.block_init) { /* '}' must be first on
- * line */
- if (verbose)
- diag(0, "Line broken");
- dump_line();
- }
- *e_code++ = '}';
- ps.want_blank = true;
- ps.in_stmt = ps.ind_stmt = false;
- if (ps.dec_nest > 0) { /* we are in multi-level structure
- * declaration */
- dec_ind = di_stack[--ps.dec_nest];
- if (ps.dec_nest == 0 && !ps.in_parameter_declaration)
- ps.just_saw_decl = 2;
- ps.in_decl = true;
- }
- prefix_blankline_requested = 0;
- parse(rbrace); /* let parser know about this */
- ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead && ps.il[ps.tos] >= ps.ind_level;
- if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0)
- postfix_blankline_requested = 1;
- break;
-
- case swstmt: /* got keyword "switch" */
- sp_sw = true;
- hd_type = swstmt; /* keep this for when we have seen the
- * expression */
- goto copy_id; /* go move the token into buffer */
-
- case sp_paren: /* token is if, while, for */
- sp_sw = true; /* the interesting stuff is done after the
- * expression is scanned */
- hd_type = (*token == 'i' ? ifstmt :
- (*token == 'w' ? whilestmt : forstmt));
-
- /* remember the type of header for later use by parser */
- goto copy_id; /* copy the token into line */
-
- case sp_nparen: /* got else, do */
- ps.in_stmt = false;
- if (*token == 'e') {
- if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) {
- if (verbose)
- diag(0, "Line broken");
- dump_line();/* make sure this starts a line */
- ps.want_blank = false;
- }
- force_nl = true;/* also, following stuff must go onto new
- * line */
- last_else = 1;
- parse(elselit);
- } else {
- if (e_code != s_code) { /* make sure this starts a
- * line */
- if (verbose)
- diag(0, "Line broken");
- dump_line();
- ps.want_blank = false;
- }
- force_nl = true;/* also, following stuff must go onto new
- * line */
- last_else = 0;
- parse(dolit);
- }
- goto copy_id; /* move the token into line */
-
- case decl: /* we have a declaration type (int, register,
- * etc.) */
- parse(decl); /* let parser worry about indentation */
- if (ps.last_token == rparen && ps.tos <= 1)
- ps.in_parameter_declaration = 1;
- if (ps.in_parameter_declaration && ps.indent_parameters && ps.dec_nest == 0) {
- ps.ind_level = ps.i_l_follow = 1;
- ps.ind_stmt = 0;
- }
- ps.in_or_st = true; /* this might be a structure or
- * initialization declaration */
- ps.in_decl = ps.decl_on_line = true;
- if ( /* !ps.in_or_st && */ ps.dec_nest <= 0)
- ps.just_saw_decl = 2;
- prefix_blankline_requested = 0;
- for (i = 0; token[i++];); /* get length of token */
-
- /* dec_ind = e_code - s_code + (ps.decl_indent>i ? ps.decl_indent
- * : i); */
- dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i;
- goto copy_id;
-
- case ident: /* got an identifier or constant */
- if (ps.in_decl) { /* if we are in a declaration, we must indent
- * identifier */
- if (ps.want_blank)
- *e_code++ = ' ';
- ps.want_blank = false;
- if (is_procname == 0 || !procnames_start_line) {
- if (!ps.block_init)
- if (troff && !ps.dumped_decl_indent) {
- sprintf(e_code, "\\c\n.De %dp+\200p\n", dec_ind * 7);
- ps.dumped_decl_indent = 1;
- e_code += strlen(e_code);
- } else
- while ((e_code - s_code) < dec_ind)
- *e_code++ = ' ';
- } else {
- if (dec_ind && s_code != e_code)
- dump_line();
- dec_ind = 0;
- ps.want_blank = false;
- }
- } else if (sp_sw && ps.p_l_follow == 0) {
- sp_sw = false;
- force_nl = true;
- ps.last_u_d = true;
- ps.in_stmt = false;
- parse(hd_type);
- }
- copy_id:
- if (ps.want_blank)
- *e_code++ = ' ';
- if (troff && ps.its_a_keyword) {
- *e_code++ = BACKSLASH;
- *e_code++ = 'f';
- *e_code++ = 'B';
- }
- for (t_ptr = token; *t_ptr; ++t_ptr)
- *e_code++ = *t_ptr;
- if (troff && ps.its_a_keyword) {
- *e_code++ = BACKSLASH;
- *e_code++ = 'f';
- *e_code++ = 'R';
- }
- ps.want_blank = true;
- break;
-
- case period: /* treat a period kind of like a binary
- * operation */
- *e_code++ = '.'; /* move the period into line */
- ps.want_blank = false; /* dont put a blank after a period */
- break;
-
- case comma:
- ps.want_blank = (s_code != e_code); /* only put blank after
- * comma if comma does
- * not start the line */
- if (ps.in_decl && is_procname == 0 && !ps.block_init)
- while ((e_code - s_code) < (dec_ind - 1))
- *e_code++ = ' ';
-
- *e_code++ = ',';
- if (ps.p_l_follow == 0) {
- ps.block_init = 0;
- if (break_comma && !ps.leave_comma)
- force_nl = true;
- }
- break;
-
- case preesc: /* got the character '#' */
- if ((s_com != e_com) || (s_lab != e_lab) || (s_code != e_code)) {
- dump_line();
- }
- *e_lab++ = '#'; /* move whole line to 'label' buffer */
-
- /* a large section of code was removed here to break these files
- * up into msc sized chunks */
- dopreesc();
-
- if (strncmp(s_lab, "#if", 3) == 0) {
- if (ifdef_level < sizeof state_stack / sizeof state_stack[0]) {
- match_state[ifdef_level].tos = -1;
- state_stack[ifdef_level++] = ps;
- } else {
- diag(1, "#if stack overflow");
- }
- } else if (strncmp(s_lab, "#else", 5) == 0) {
- if (ifdef_level <= 0) {
- diag(1, "Unmatched #else");
- } else {
- match_state[ifdef_level - 1] = ps;
- ps = state_stack[ifdef_level - 1];
- }
- } else if (strncmp(s_lab, "#endif", 6) == 0) {
- if (ifdef_level <= 0) {
- diag(1, "Unmatched #endif");
- } else {
- ifdef_level--;
- #ifdef undef
-
- /* This match needs to be more intelligent before the
- * message is useful */
- if (match_state[ifdef_level].tos >= 0
- && /* bcmp */ memcmp(&ps, &match_state[ifdef_level], sizeof ps))
- diag(0, "Syntactically inconsistant #ifdef alternatives.");
- #endif
- }
- }
- break; /* subsequent processing of the newline
- * character will cause the line to be
- * printed */
-
- case comment: /* we have gotten a /* this is a biggie */
- proc_comment:
- if (flushed_nl) { /* we should force a broken line here */
- flushed_nl = false;
- dump_line();
- ps.want_blank = false; /* dont insert blank at line start */
- force_nl = false;
- }
- pr_comment();
- break;
- } /* end of big switch stmt */
- }
-