Category : C Source Code
Archive   : INDENT.ZIP
Filename : DOINDENT.C

 
Output of file : DOINDENT.C contained in archive : INDENT.ZIP
#include "indent_c.h"
#include "indent_g.h"

extern int dec_ind; /* current indentation for declarations */
extern int di_stack[20]; /* 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 ?:
* 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;


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
* ?: 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 ?:
* 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 '{' */
ps.in_stmt = false; /* dont indent the {} */
if (!ps.block_init)
force_nl = true; /* force other stuff on same
* line as '{' 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(&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 */
}


  3 Responses to “Category : C Source Code
Archive   : INDENT.ZIP
Filename : DOINDENT.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/