static char sccsid
[] = "@(#)io.c 4.1 (Berkeley) %G%";
Contains routines to handle i/o related stuff for indent.
Does the actual printing of the stored up line
For each of the label, code, and comment sections which are used on
1) Use pad_output to get the section aligned properly.
The indentation level used for the code is set by ind_level. After
printing, ind_level is set to i_l_follow.
An extra level of indentation is added if ind_stmt is 1. After
printing, ind_stmt is set to 1 iff the line just printed has an
unterminated, non-declaration statement.
bl_line = Set to true iff the line was blank
code_lines = Count lines with code
com_lines = Keep track of lines with comments
decl_on_line = Set to in_decl after line is printed
ind_level = Set to i_l_follow at completion
ind_stmt = Set to in_stmt at completion if not in declaration
out_lines = Count output lines
paren_level = Set to p_l_follow at completion
initial coding November 1976 D A Willcox of CAC
#include "indent_globs.h";
int ff
= 014; /* used to write a form feed */
dump_line () { /* dump_line is the routine that actually
effects the printing of the new source.
It prints the label section, followed by
the code section with the appropriate
nesting level, followed by any comments
bl_line
= true; /* if we don't find otherwise, assume a
ind_stmt
= 0; /* this is a class A kludge. don't do
additional statement indentation if we
are at bracket level 0 */
if (e_lab
!= s_lab
|| e_code
!= s_code
)
++code_lines
; /* keep count of lines with code */
if (e_lab
!= s_lab
) { /* print lab, if any */
if (pcase
) /* if the label is really a case, we must
cur_col
= pad_output (1, case_ind
* ind_size
+ 1);
if (*s_lab
== '#') /* check for #define, etc */
cur_col
= pad_output (1, ind_size
* (ind_level
- label_offset
) + 1);
write (output
, s_lab
, e_lab
- s_lab
);
cur_col
= count_spaces (cur_col
, s_lab
);
/* count_spaces gives number of characters, considering tabs */
bl_line
= false; /* line not blank after all */
cur_col
= 1; /* there is no label section */
if (s_code
!= e_code
) { /* print code section, if any */
target_col
= ind_size
* (ind_level
+ paren_level
+ ind_stmt
) + 1;
cur_col
= pad_output (cur_col
, target_col
);
/* pad_output writes enough tabs and spaces to get the current char
position up to target_col */
write (output
, s_code
, e_code
- s_code
);
cur_col
= count_spaces (cur_col
, s_code
);
bl_line
= false; /* line not blank */
if ((cur_col
- 1) > max_col
&& output
!=1)/* check for line too long */
printf ("%d: Code has %d chars, max is %d\n", line_no
, (cur_col
- 1), max_col
);
if (s_com
!= e_com
) { /* print comment, if any */
if (cur_col
> com_col
&& count_spaces (cur_col
, s_com
) >= max_col
) {
/* if comment can't fit on this line, put it on next line */
cur_col
= pad_output (cur_col
, com_col
);
write (output
, s_com
, e_com
- s_com
);
cur_col
= count_spaces (cur_col
, s_com
);
if ((cur_col
- 1) > max_col
&& output
!=1)/* check for too long comment */
printf ("%d: Comment goes to column %d. Max is %d\n",
line_no
, (cur_col
- 1), max_col
);
++com_lines
; /* count lines with comments */
write (output
, &ff
, 1);/* end the output with a ff */
write (output
, "\n", 1); /* or a newline */
*(e_lab
= s_lab
) = '\0'; /* reset buffers */
*(e_code
= s_code
) = '\0';
paren_level
= p_l_follow
;
decl_on_line
= in_decl
; /* if we are in the middle of a
declaration, remember that fact for
proper comment indentation */
ind_stmt
= in_stmt
& ~in_decl
;
/* next line should be indented if we have not completed this stmt and if
we are not in the middle of a declaration */
Reads one block of input into input_buffer
buf_end = Set to 1 past last character read in
buf_ptr = Set to start of buffer
be_save = Set to zero if it was non-zero
initial coding November 1976 D A Willcox of CAC
1/7/77 D A Willcox of CAC Added check for switch back to
partly full input buffer from
int fill_buffer () { /* this routine reads stuff from the input */
if (bp_save
!= 0) { /* there is a partly filled input buffer
buf_ptr
= bp_save
; /* don't read anything, just switch buffers
return; /* only return if there is really something
count
= read (input
, in_buffer
, inp_bufs
);
buf_end
= in_buffer
+ count
;
if (count
== 0) { /* count of zero means eof */
*buf_end
++ = '\n'; /* insert extra newline. it will
eventually get indent to stop */
Writes tabs and spaces to move the current column up to the
Put tabs and/or blanks into pobuf, then write pobuf.
current integer The current column
target integer The desired column
Integer value of the new column. (If current >= target,
no action is taken, and current is returned.
initial coding November 1976 D A Willcox of CAC
int pad_output (current
, target
)/* writes tabs and blanks (if necessary) to
get the current output position up to
int current
; /* the current column value */
int target
; /* position we want it at */
register int curr
; /* internal column pointer */
register char *p
; /* pointer into buffer of characters to be written */
char pobuf
[256]; /* pad characters are stored here before writing */
return (current
); /* line is already long enough */
if ((tcur
= ((curr
- 1) & tabmask
) + tabsize
+ 1) <= target
){
*p
++ = '\t'; /* put a tab into buffer */
*p
++ = ' '; /* pad with final blanks */
write (output
, pobuf
, p
- pobuf
); /* write the characters we saved */
Find out where printing of a given string will leave the current
character position on output.
Run thru input string and add appropriate values to current position.
current integer The current line character position
buffer ptr to character Pointer to input string
Integer value of position after printing "buffer" starting in
initial coding November 1976 D A Willcox of CAC
int count_spaces (current
, buffer
)
/* this routine figures out where the
character position will be after
printing the text in buffer starting at
register char *buf
; /* used to look thru buffer */
register int cur
; /* current character counter */
for (buf
= buffer
; *buf
!= '\0'; ++buf
) {
case 014: /* form feed */
cur
= ((cur
- 1) & tabmask
) + tabsize
+ 1;
case '\b': /* this is a backspace */
Returns true if the first arg matches the beginning of the second arg.
str1 pointer to character
str2 pointer to character
1 if first string matches start of second string
initial coding November 1976 by D A Willcox of CAC
register char *s1
; /* local pointer into first string */
register char *s2
; /* local pointer into second string */
while (*s1
) { /* compare no further than end of first
if (*s2
== 0) /* check that second string isn't too short
a Pointer to char First string to compare
b Pointer to char Second string to compare
1/7/77 D A Willcox of CAC Initial Coding