* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980 The Regents of the University of California.
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* %sccs.include.redist.c%
"@(#) Copyright (c) 1985 Sun Microsystems, Inc.\n\
@(#) Copyright (c) 1980 The Regents of the University of California.\n\
@(#) Copyright (c) 1976 Board of Trustees of the University of Illinois.\n\
static char sccsid
[] = "@(#)indent.c 5.16 (Berkeley) %G%";
#include "indent_globs.h"
#include "indent_codes.h"
char *in_name
= "Standard Input"; /* will always point to name of input
char *out_name
= "Standard Output"; /* will always point to name
char bakfile
[MAXPATHLEN
] = "";
extern int found_err
; /* flag set in diag() on error */
int dec_ind
; /* current indentation for declarations */
int di_stack
[20]; /* a stack of structure indentation levels */
int flushed_nl
; /* used when buffering up comments to remember
* that a newline was passed over */
int force_nl
; /* when true, code must be broken */
int hd_type
; /* used to store type of stmt for if (...),
register int i
; /* local loop counter */
int scase
; /* set to true when we see a case, so we will
* know what to do with the following colon */
int sp_sw
; /* when true, we are in the expressin of
* if(...), while(...), etc. */
int squest
; /* when this is positive, we have seen a ?
* without the matching : in a <c>?<s>:<s>
register char *t_ptr
; /* used for copying tokens */
int type_code
; /* the type of token, returned by lexi */
int last_else
= 0; /* true iff last keyword was an else */
/*-----------------------------------------------*\
\*-----------------------------------------------*/
ps
.p_stack
[0] = stmt
; /* this is the parser's stack */
ps
.last_nl
= true; /* this is true if the last thing scanned was
ps
.last_token
= semicolon
;
combuf
= (char *) malloc(bufsize
);
labbuf
= (char *) malloc(bufsize
);
codebuf
= (char *) malloc(bufsize
);
tokenbuf
= (char *) malloc(bufsize
);
l_com
= combuf
+ bufsize
- 5;
l_lab
= labbuf
+ bufsize
- 5;
l_code
= codebuf
+ bufsize
- 5;
l_token
= tokenbuf
+ bufsize
- 5;
combuf
[0] = codebuf
[0] = labbuf
[0] = ' '; /* set up code, label, and
combuf
[1] = codebuf
[1] = labbuf
[1] = '\0';
ps
.else_if
= 1; /* Default else-if special processing to on */
s_lab
= e_lab
= labbuf
+ 1;
s_code
= e_code
= codebuf
+ 1;
s_com
= e_com
= combuf
+ 1;
s_token
= e_token
= tokenbuf
+ 1;
in_buffer
= (char *) malloc(10);
in_buffer_limit
= in_buffer
+ 8;
buf_ptr
= buf_end
= in_buffer
;
had_eof
= ps
.in_decl
= ps
.decl_on_line
= break_comma
= false;
sp_sw
= force_nl
= false;
di_stack
[ps
.dec_nest
= 0] = 0;
ps
.want_blank
= ps
.in_stmt
= ps
.ind_stmt
= false;
scase
= ps
.pcase
= false;
/*--------------------------------------------------*\
\*--------------------------------------------------*/
lineup_to_parens
= 1; /* -lp */
ps
.ljust_decl
= 0; /* -ndj */
ps
.com_ind
= 33; /* -c33 */
star_comment_cont
= 1; /* -sc */
ps
.ind_size
= 8; /* -i8 */
ps
.decl_indent
= 16; /* -di16 */
ps
.indent_parameters
= 1; /* -ip */
ps
.decl_com_ind
= 0; /* if this is not set to some positive value
* by an arg, we will set this equal to
cuddle_else
= 1; /* -ce */
ps
.unindent_displace
= 0; /* -d0 */
ps
.case_indent
= 0; /* -cli0 */
format_col1_comments
= 1; /* -fc1 */
procnames_start_line
= 1; /* -psl */
proc_calls_space
= 0; /* -npcs */
comment_delimiter_on_blankline
= 1; /* -cdb */
ps
.leave_comma
= 1; /* -nbc */
for (i
= 1; i
< argc
; ++i
)
if (strcmp(argv
[i
], "-npro") == 0)
for (i
= 1; i
< argc
; ++i
) {
* look thru args (if any) for changes to defaults
if (argv
[i
][0] != '-') {/* no flag on parameter */
if (input
== 0) { /* we must have the input file */
in_name
= argv
[i
]; /* remember name of input file */
input
= fopen(in_name
, "r");
if (input
== 0) /* check for open error */
else if (output
== 0) { /* we have the output file */
out_name
= argv
[i
]; /* remember name of output file */
if (strcmp(in_name
, out_name
) == 0) { /* attempt to overwrite
fprintf(stderr
, "indent: input and output files must be different\n");
output
= fopen(out_name
, "w");
if (output
== 0) /* check for create error */
fprintf(stderr
, "indent: unknown parameter: %s\n", argv
[i
]);
fprintf(stderr
, "indent: usage: indent file [ outfile ] [ options ]\n");
ps
.com_ind
= 2; /* dont put normal comments before column 2 */
if (blkcomf
.font
[0] == 0)
blkcomf
= scomf
, blkcomf
.size
+= 2;
if (boxcomf
.font
[0] == 0)
if (stringf
.font
[0] == 0)
parsefont(&stringf
, "L");
if (keywordf
.font
[0] == 0)
parsefont(&keywordf
, "B");
writefdef(&blkcomf
, 'L');
writefdef(&boxcomf
, 'X');
writefdef(&stringf
, 'S');
writefdef(&keywordf
, 'K');
if (block_comment_max_col
<= 0)
block_comment_max_col
= max_col
;
if (ps
.decl_com_ind
<= 0) /* if not specified by user, set this */
ps
.decl_com_ind
= ps
.ljust_decl
? (ps
.com_ind
<= 10 ? 2 : ps
.com_ind
- 8) : ps
.com_ind
;
if (continuation_indent
== 0)
continuation_indent
= ps
.ind_size
;
fill_buffer(); /* get first batch of stuff into input buffer */
register char *p
= buf_ptr
;
col
= ((col
- 1) & ~7) + 9;
ps
.ind_level
= ps
.i_l_follow
= col
/ ps
.ind_size
;
register char *p
= in_name
,
fprintf(output
, ".Fn \"%s\"\n", beg
);
while (1) { /* this is the main loop. it will go until we
type_code
= lexi(); /* lexi reads one token. The actual
* characters read are stored in "token". lexi
* returns a code indicating the type of token */
is_procname
= ps
.procname
[0];
* The following code moves everything following an if (), while (),
* else, etc. up to the start of the following stmt to a buffer. This
* allows proper handling of both kinds of brace placement.
while (ps
.search_brace
) { /* if we scanned an if(), while(),
* etc., we might need to copy stuff
* into a buffer we must loop, copying
* stuff into save_com, until we find
* the start of the stmt which follows
break; /* form feeds and newlines found here will be
case lbrace
: /* this is a brace that starts the compound
if (sc_end
== 0) { /* ignore buffering if a comment wasnt
save_com
[0] = '{'; /* we either want to put the brace
goto sw_buffer
; /* go to common code to get out of
case comment
: /* we have a comment, so we must copy it into
if (!flushed_nl
|| sc_end
!= 0) {
if (sc_end
== 0) { /* if this is the first comment, we
* must set up the buffer */
save_com
[0] = save_com
[1] = ' ';
*sc_end
++ = '\n'; /* add newline between
*sc_end
++ = '/'; /* copy in start of comment */
for (;;) { /* loop until we get to the end of the comment */
if (*sc_end
++ == '*' && *buf_ptr
== '/')
break; /* we are at end of comment */
if (sc_end
>= &(save_com
[sc_size
])) { /* check for temp buffer
diag(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever.");
*sc_end
++ = '/'; /* add ending slash */
if (++buf_ptr
>= buf_end
) /* get past / in buffer */
default: /* it is the start of a normal statment */
if (flushed_nl
) /* if we flushed a newline, make sure it is
if (type_code
== sp_paren
&& *token
== 'i'
&& last_else
&& ps
.else_if
|| type_code
== sp_nparen
&& *token
== 'e'
&& e_code
!= s_code
&& e_code
[-1] == '}')
if (sc_end
== 0) { /* ignore buffering if comment wasnt
if (force_nl
) { /* if we should insert a nl here, put it into
--line_no
; /* this will be re-increased when the nl is
* read from the buffer */
if (verbose
&& !flushed_nl
) /* print error msg if the line
* was not already broken */
for (t_ptr
= token
; *t_ptr
; ++t_ptr
)
*sc_end
++ = *t_ptr
; /* copy token into temp buffer */
ps
.search_brace
= false; /* stop looking for start of
bp_save
= buf_ptr
; /* save current input buffer */
buf_ptr
= save_com
; /* fix so that subsequent calls to
* lexi will take tokens out of
*sc_end
++ = ' ';/* add trailing blank, just in case */
if (type_code
!= 0) /* we must make this check, just in case there
* was an unexpected EOF */
type_code
= lexi(); /* read another token */
/* if (ps.search_brace) ps.procname[0] = 0; */
if ((is_procname
= ps
.procname
[0]) && flushed_nl
&& !procnames_start_line
&& ps
.in_decl
} /* end of while (search_brace) */
if (type_code
== 0) { /* we got eof */
if (s_lab
!= e_lab
|| s_code
!= e_code
|| s_com
!= e_com
) /* must dump end of line */
if (ps
.tos
> 1) /* check for balanced braces */
diag(1, "Stuff missing from end of file.");
printf("There were %d output lines and %d comments\n",
ps
.out_lines
, ps
.out_coms
);
printf("(Lines with comments)/(Lines with code): %6.3f\n",
(1.0 * ps
.com_lines
) / code_lines
);
(type_code
!= comment
) &&
(type_code
!= newline
) &&
(type_code
!= form_feed
)) {
(type_code
!= semicolon
) &&
(type_code
!= lbrace
|| !btype_2
)) {
/* we should force a broken line here */
if (verbose
&& !flushed_nl
)
ps
.want_blank
= false; /* dont insert blank at line start */
ps
.in_stmt
= true; /* turn on flag which causes an extra level of
* indentation. this is turned off by a ; or
if (s_com
!= e_com
) { /* the turkey has embedded a comment
for (t_ptr
= s_com
; *t_ptr
; ++t_ptr
) {
*e_code
= '\0'; /* null terminate code sect */
else if (type_code
!= comment
) /* preserve force_nl thru a comment */
force_nl
= false; /* cancel forced newline after newline, form
/*-----------------------------------------------------*\
| 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 */
if (ps
.last_token
!= comma
|| ps
.p_l_follow
> 0
|| !ps
.leave_comma
|| ps
.block_init
|| !break_comma
|| s_com
!= e_com
) {
++line_no
; /* keep track of input line number */
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
|| Bill_Shannon
))))
if (ps
.in_decl
&& !ps
.block_init
)
if (troff
&& !ps
.dumped_decl_indent
&& !is_procname
&& ps
.last_token
== decl
) {
ps
.dumped_decl_indent
= 1;
sprintf(e_code
, "\n.Du %dp+\200p \"%s\"\n", dec_ind
* 7, token
);
e_code
+= strlen(e_code
);
while ((e_code
- s_code
) < dec_ind
) {
ps
.paren_indents
[ps
.p_l_follow
- 1] = e_code
- s_code
;
if (sp_sw
&& ps
.p_l_follow
== 1 && extra_expression_indent
&& ps
.paren_indents
[0] < 2 * ps
.ind_size
)
ps
.paren_indents
[0] = 2 * ps
.ind_size
;
if (ps
.in_or_st
&& *token
== '(' && ps
.tos
<= 2) {
* this is a kluge to make sure that declarations will be
* aligned right if proc decl has an explicit type on it, i.e.
parse(semicolon
); /* I said this was a kluge... */
ps
.in_or_st
= false; /* turn off flag for structure decl or
ps
.sizeof_mask
|= 1 << ps
.p_l_follow
;
case rparen
: /* got a ')' or ']' */
if (ps
.cast_mask
& (1 << ps
.p_l_follow
) & ~ps
.sizeof_mask
) {
ps
.cast_mask
&= (1 << ps
.p_l_follow
) - 1;
ps
.sizeof_mask
&= (1 << ps
.p_l_follow
) - 1;
if (--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 */
if (sp_sw
&& (ps
.p_l_follow
== 0)) { /* check for end of if
force_nl
= true;/* must force newline after if */
ps
.last_u_d
= true; /* inform lexi that a following
ps
.in_stmt
= false; /* dont use stmt continuation
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
case unary_op
: /* this could be any unary operation */
if (troff
&& !ps
.dumped_decl_indent
&& ps
.in_decl
&& !is_procname
) {
sprintf(e_code
, "\n.Du %dp+\200p \"%s\"\n", dec_ind
* 7, token
);
ps
.dumped_decl_indent
= 1;
e_code
+= strlen(e_code
);
if (ps
.in_decl
&& !ps
.block_init
) { /* if this is a unary op
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] == '>')
for (t_ptr
= res
; *t_ptr
; ++t_ptr
) {
case binary_op
: /* any binary operation */
for (t_ptr
= res
; *t_ptr
; ++t_ptr
) {
*e_code
++ = *t_ptr
; /* move the operator */
case postop
: /* got a trailing ++ or -- */
case question
: /* got a ? */
squest
++; /* this will be used when a later colon
* appears so we can distinguish the
* <c>?<n>:<n> construct */
case casestmt
: /* got word 'case' or 'default' */
scase
= true; /* so we can process the later colon properly */
case colon
: /* got a ':' */
if (squest
> 0) { /* it is part of the <c>?<n>: <n> construct */
ps
.in_stmt
= false; /* seeing a label does not imply we are in a
for (t_ptr
= s_code
; *t_ptr
; ++t_ptr
)
*e_lab
++ = *t_ptr
; /* turn everything so far into a label */
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
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 */
if (ps
.last_token
== rparen
&& rparen_count
== 0)
ps
.in_parameter_declaration
= 0;
if (ps
.in_decl
&& s_code
== e_code
&& !ps
.block_init
)
while ((e_code
- s_code
) < (dec_ind
- 1)) {
ps
.in_decl
= (ps
.dec_nest
> 0); /* if we were in a first level
* structure declaration, we
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
diag(1, "Unbalanced parens");
if (sp_sw
) { /* this is a check for a if, while, etc. with
parse(hd_type
); /* dont lose the if, or whatever */
ps
.in_stmt
= (ps
.p_l_follow
> 0); /* we are no longer in the
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 */
case lbrace
: /* got a '{' */
ps
.in_stmt
= false; /* dont indent the {} */
force_nl
= true;/* force other stuff on same line as '{' onto
else if (ps
.block_init_level
<= 0)
if (s_code
!= e_code
&& !ps
.block_init
) {
else if (ps
.in_parameter_declaration
&& !ps
.in_or_st
) {
if (ps
.in_parameter_declaration
)
prefix_blankline_requested
= 0;
if (ps
.p_l_follow
> 0) { /* check for preceeding unbalanced
diag(1, "Unbalanced parens");
if (sp_sw
) { /* check for unclosed if, for, etc. */
ps
.ind_level
= ps
.i_l_follow
;
ps
.ind_stmt
= false; /* dont put extra indentation on line
if (ps
.in_decl
&& ps
.in_or_st
) { /* this is either a structure
* declaration or an init */
di_stack
[ps
.dec_nest
++] = dec_ind
;
ps
.decl_on_line
= false; /* we cant be in the middle of
* a declaration, so dont do
if (blanklines_after_declarations_at_proctop
&& ps
.in_parameter_declaration
)
postfix_blankline_requested
= 1;
ps
.in_parameter_declaration
= 0;
parse(lbrace
); /* let parser know about this */
if (ps
.want_blank
) /* put a blank before '{' if '{' is not at
case rbrace
: /* got a '}' */
if (ps
.p_stack
[ps
.tos
] == decl
&& !ps
.block_init
) /* semicolons can be
if (ps
.p_l_follow
) {/* check for unclosed if, for, else. */
diag(1, "Unbalanced parens");
if (s_code
!= e_code
&& !ps
.block_init
) { /* '}' must be first on
ps
.in_stmt
= ps
.ind_stmt
= false;
if (ps
.dec_nest
> 0) { /* we are in multi-level structure
dec_ind
= di_stack
[--ps
.dec_nest
];
if (ps
.dec_nest
== 0 && !ps
.in_parameter_declaration
)
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;
case swstmt
: /* got keyword "switch" */
hd_type
= swstmt
; /* keep this for when we have seen the
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 */
if (e_code
!= s_code
&& (!cuddle_else
|| e_code
[-1] != '}')) {
dump_line();/* make sure this starts a line */
force_nl
= true;/* also, following stuff must go onto new line */
if (e_code
!= s_code
) { /* make sure this starts a line */
force_nl
= true;/* also, following stuff must go onto new line */
goto copy_id
; /* move the token into line */
case decl
: /* we have a declaration type (int, register,
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
.in_or_st
= true; /* this might be a structure or initialization
ps
.in_decl
= ps
.decl_on_line
= true;
if ( /* !ps.in_or_st && */ ps
.dec_nest
<= 0)
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
dec_ind
= ps
.decl_indent
> 0 ? ps
.decl_indent
: i
;
case ident
: /* got an identifier or constant */
if (ps
.in_decl
) { /* if we are in a declaration, we must indent
if (is_procname
== 0 || !procnames_start_line
) {
if (troff
&& !ps
.dumped_decl_indent
) {
sprintf(e_code
, "\n.De %dp+\200p\n", dec_ind
* 7);
ps
.dumped_decl_indent
= 1;
e_code
+= strlen(e_code
);
while ((e_code
- s_code
) < dec_ind
) {
if (dec_ind
&& s_code
!= e_code
)
else if (sp_sw
&& ps
.p_l_follow
== 0) {
if (troff
&& ps
.its_a_keyword
) {
e_code
= chfont(&bodyf
, &keywordf
, e_code
);
for (t_ptr
= token
; *t_ptr
; ++t_ptr
) {
*e_code
++ = keywordf
.allcaps
&& islower(*t_ptr
)
? toupper(*t_ptr
) : *t_ptr
;
e_code
= chfont(&keywordf
, &bodyf
, e_code
);
for (t_ptr
= token
; *t_ptr
; ++t_ptr
) {
case period
: /* treat a period kind of like a binary
*e_code
++ = '.'; /* move the period into line */
ps
.want_blank
= false; /* dont put a blank after a period */
ps
.want_blank
= (s_code
!= e_code
); /* only put blank after comma
* if comma does not start the
if (ps
.in_decl
&& is_procname
== 0 && !ps
.block_init
)
while ((e_code
- s_code
) < (dec_ind
- 1)) {
if (ps
.p_l_follow
== 0) {
if (ps
.block_init_level
<= 0)
if (break_comma
&& (!ps
.leave_comma
|| compute_code_target() + (e_code
- s_code
) > max_col
- 8))
case preesc
: /* got the character '#' */
*e_lab
++ = '#'; /* move whole line to 'label' buffer */
while (*buf_ptr
== ' ' || *buf_ptr
== '\t') {
while (*buf_ptr
!= '\n' || in_comment
) {
if (*buf_ptr
== '*' && !in_comment
&& !quote
) {
com_start
= e_lab
- s_lab
- 2;
if (*buf_ptr
== '/' && in_comment
) {
while (e_lab
> s_lab
&& (e_lab
[-1] == ' ' || e_lab
[-1] == '\t'))
if (e_lab
- s_lab
== com_end
&& bp_save
== 0) { /* comment on
if (sc_end
== 0) /* if this is the first comment, we
* must set up the buffer */
*sc_end
++ = '\n'; /* add newline between
bcopy(s_lab
+ com_start
, sc_end
, com_end
- com_start
);
sc_end
+= com_end
- com_start
;
if (sc_end
>= &save_com
[sc_size
])
e_lab
= s_lab
+ com_start
;
while (e_lab
> s_lab
&& (e_lab
[-1] == ' ' || e_lab
[-1] == '\t'))
bp_save
= buf_ptr
; /* save current input buffer */
buf_ptr
= save_com
; /* fix so that subsequent calls to
* lexi will take tokens out of
*sc_end
++ = ' '; /* add trailing blank, just in case */
*e_lab
= '\0'; /* null terminate line */
if (strncmp(s_lab
, "#if", 3) == 0) {
if (blanklines_around_conditional_compilation
) {
prefix_blankline_requested
++;
while ((c
= getc(input
)) == '\n');
if (ifdef_level
< sizeof state_stack
/ sizeof state_stack
[0]) {
match_state
[ifdef_level
].tos
= -1;
state_stack
[ifdef_level
++] = ps
;
diag(1, "#if stack overflow");
else if (strncmp(s_lab
, "#else", 5) == 0)
diag(1, "Unmatched #else");
match_state
[ifdef_level
- 1] = ps
;
ps
= state_stack
[ifdef_level
- 1];
else if (strncmp(s_lab
, "#endif", 6) == 0) {
diag(1, "Unmatched #endif");
* This match needs to be more intelligent before the
if (match_state
[ifdef_level
].tos
>= 0
&& bcmp(&ps
, &match_state
[ifdef_level
], sizeof ps
))
diag(0, "Syntactically inconsistant #ifdef alternatives.");
if (blanklines_around_conditional_compilation
) {
postfix_blankline_requested
++;
break; /* subsequent processing of the newline
* character will cause the line to be printed */
case comment
: /* we have gotten a /* this is a biggie */
if (flushed_nl
) { /* we should force a broken line here */
ps
.want_blank
= false; /* dont insert blank at line start */
} /* end of big switch stmt */
*e_code
= '\0'; /* make sure code section is null terminated */
if (type_code
!= comment
&& type_code
!= newline
&& type_code
!= preesc
)
ps
.last_token
= type_code
;
} /* end of main while (1) loop */
* copy input file to backup file if in_name is /blah/blah/blah/file, then
* backup file will be ".Bfile" then make the backup file the input and
* original input file the output
/* construct file name .Bfile */
for (p
= in_name
; *p
; p
++); /* skip to end of string */
while (p
> in_name
&& *p
!= '/') /* find last '/' */
sprintf(bakfile
, "%s.BAK", p
);
/* copy in_name to backup file */
bakchn
= creat(bakfile
, 0600);
while (n
= read(fileno(input
), buff
, sizeof buff
))
if (write(bakchn
, buff
, n
) != n
)
/* re-open backup file as the input file */
input
= fopen(bakfile
, "r");
/* now the original input file will be the output */
output
= fopen(in_name
, "w");
(void)fprintf(stderr
, "indent: %s: %s\n", msg
, strerror(errno
));