date and time created 83/02/11 15:44:54 by rrh
[unix-history] / usr / src / usr.bin / indent / io.c
CommitLineData
87ba9e01
KM
1static char sccsid[] = "@(#)io.c 4.1 (Berkeley) %G%";
2
3/*
4
5 Copyright (C) 1976
6 by the
7 Board of Trustees
8 of the
9 University of Illinois
10
11 All rights reserved
12
13
14FILE NAME:
15 io.c
16
17PURPOSE:
18 Contains routines to handle i/o related stuff for indent.
19
20GLOBALS:
21 None
22
23FUNCTIONS:
24 dump_line
25 fill_buffer
26 pad_output
27 count_spaces
28 eqin
29 cmp
30
31*/\f
32/*
33
34 Copyright (C) 1976
35 by the
36 Board of Trustees
37 of the
38 University of Illinois
39
40 All rights reserved
41
42
43NAME:
44 dump_line
45
46FUNCTION:
47 Does the actual printing of the stored up line
48
49ALGORITHM:
50 For each of the label, code, and comment sections which are used on
51 this line:
52
53 1) Use pad_output to get the section aligned properly.
54 2) write the section
55
56 The indentation level used for the code is set by ind_level. After
57 printing, ind_level is set to i_l_follow.
58
59 An extra level of indentation is added if ind_stmt is 1. After
60 printing, ind_stmt is set to 1 iff the line just printed has an
61 unterminated, non-declaration statement.
62
63PARAMETERS:
64 None
65
66RETURNS:
67 Nothing
68
69GLOBALS:
70 labbuf
71 s_lab
72 e_lab = Reset to s_lab
73
74 codebuf
75 s_code
76 e_code = Reset to s_code
77
78 combuf
79 s_com
80 e_com = Reset to s_com
81
82 bl_line = Set to true iff the line was blank
83 case_ind
84 code_lines = Count lines with code
85 com_col
86 com_lines = Keep track of lines with comments
87 decl_on_line = Set to in_decl after line is printed
88 i_l_follow
89 in_decl
90 in_stmt
91 ind_level = Set to i_l_follow at completion
92 ind_size
93 ind_stmt = Set to in_stmt at completion if not in declaration
94 out_lines = Count output lines
95 p_l_follow
96 paren_level = Set to p_l_follow at completion
97 pcase
98 use_ff = Reset to false
99
100CALLS:
101 pad_output
102 printf (lib)
103 write (lib)
104
105CALLED BY:
106 main
107 pr_comment
108
109HISTORY:
110 initial coding November 1976 D A Willcox of CAC
111
112*/\f
113#include "indent_globs.h";
114
115
116
117int ff = 014; /* used to write a form feed */
118
119
120dump_line () { /* dump_line is the routine that actually
121 effects the printing of the new source.
122 It prints the label section, followed by
123 the code section with the appropriate
124 nesting level, followed by any comments
125 */
126 register int cur_col,
127 temp_col,
128 target_col;
129
130 bl_line = true; /* if we don't find otherwise, assume a
131 blank line */
132
133 if (ind_level == 0)
134 ind_stmt = 0; /* this is a class A kludge. don't do
135 additional statement indentation if we
136 are at bracket level 0 */
137
138 if (e_lab != s_lab || e_code != s_code)
139 ++code_lines; /* keep count of lines with code */
140
141 if (e_lab != s_lab) { /* print lab, if any */
142 if (pcase) /* if the label is really a case, we must
143 indent */
144 cur_col = pad_output (1, case_ind * ind_size + 1);
145 else {
146 if (*s_lab == '#') /* check for #define, etc */
147 cur_col = 1;
148 else
149 cur_col = pad_output (1, ind_size * (ind_level - label_offset) + 1);
150 }
151
152 write (output, s_lab, e_lab - s_lab);
153 cur_col = count_spaces (cur_col, s_lab);
154 /* count_spaces gives number of characters, considering tabs */
155 bl_line = false; /* line not blank after all */
156 }
157 else
158 cur_col = 1; /* there is no label section */
159
160 pcase = false;
161
162 if (s_code != e_code) { /* print code section, if any */
163 target_col = ind_size * (ind_level + paren_level + ind_stmt) + 1;
164
165 cur_col = pad_output (cur_col, target_col);
166 /* pad_output writes enough tabs and spaces to get the current char
167 position up to target_col */
168 write (output, s_code, e_code - s_code);
169 cur_col = count_spaces (cur_col, s_code);
170 bl_line = false; /* line not blank */
171 }
172
173 if ((cur_col - 1) > max_col && output!=1)/* check for line too long */
174 printf ("%d: Code has %d chars, max is %d\n", line_no, (cur_col - 1), max_col);
175
176 if (s_com != e_com) { /* print comment, if any */
177 if (cur_col > com_col && count_spaces (cur_col, s_com) >= max_col) {
178 /* if comment can't fit on this line, put it on next line */
179 write (output, "\n", 1);
180 cur_col = 1;
181 ++out_lines;
182 }
183 cur_col = pad_output (cur_col, com_col);
184 write (output, s_com, e_com - s_com);
185
186 cur_col = count_spaces (cur_col, s_com);
187 if ((cur_col - 1) > max_col && output!=1)/* check for too long comment */
188 printf ("%d: Comment goes to column %d. Max is %d\n",
189 line_no, (cur_col - 1), max_col);
190
191 bl_line = false;
192 ++com_lines; /* count lines with comments */
193 }
194
195 if (use_ff)
196 write (output, &ff, 1);/* end the output with a ff */
197 else
198 write (output, "\n", 1); /* or a newline */
199 use_ff = false;
200 *(e_lab = s_lab) = '\0'; /* reset buffers */
201 *(e_code = s_code) = '\0';
202 *(e_com = s_com) = '\0';
203
204 ind_level = i_l_follow;
205 paren_level = p_l_follow;
206 ++out_lines;
207 decl_on_line = in_decl; /* if we are in the middle of a
208 declaration, remember that fact for
209 proper comment indentation */
210 ind_stmt = in_stmt & ~in_decl;
211 /* next line should be indented if we have not completed this stmt and if
212 we are not in the middle of a declaration */
213
214 return;
215};
216\f/*
217
218 Copyright (C) 1976
219 by the
220 Board of Trustees
221 of the
222 University of Illinois
223
224 All rights reserved
225
226
227NAME:
228 fill_buffer
229
230FUNCTION:
231 Reads one block of input into input_buffer
232
233ALGORITHM:
234 Trivial
235
236PARAMETERS:
237 None
238
239RETURNS:
240 Nothing
241
242GLOBALS:
243 in_buffer =
244 buf_end = Set to 1 past last character read in
245 buf_ptr = Set to start of buffer
246 be_save = Set to zero if it was non-zero
247 bp_save = Set to zero
248
249CALLS:
250 read (lib)
251
252CALLED BY:
253 lexi
254 main
255 pr_comment
256
257HISTORY:
258 initial coding November 1976 D A Willcox of CAC
259 1/7/77 D A Willcox of CAC Added check for switch back to
260 partly full input buffer from
261 temporary buffer
262
263*/\f
264int fill_buffer () { /* this routine reads stuff from the input */
265 int count;
266 register int i;
267
268 if (bp_save != 0) { /* there is a partly filled input buffer
269 left */
270 buf_ptr = bp_save; /* don't read anything, just switch buffers
271 */
272 buf_end = be_save;
273 bp_save = be_save = 0;
274 if (buf_ptr < buf_end)
275 return; /* only return if there is really something
276 in this buffer */
277 }
278
279 count = read (input, in_buffer, inp_bufs);
280
281 buf_end = in_buffer + count;
282 buf_ptr = in_buffer;
283
284 if (count == 0) { /* count of zero means eof */
285 had_eof = true;
286 *buf_end++ = ' ';
287 *buf_end++ = '\n'; /* insert extra newline. it will
288 eventually get indent to stop */
289 }
290
291 return;
292};
293\f/*
294
295 Copyright (C) 1976
296 by the
297 Board of Trustees
298 of the
299 University of Illinois
300
301 All rights reserved
302
303
304NAME:
305 pad_output
306
307FUNCTION:
308 Writes tabs and spaces to move the current column up to the
309 desired position.
310
311ALGORITHM:
312 Put tabs and/or blanks into pobuf, then write pobuf.
313
314PARAMETERS:
315 current integer The current column
316 target integer The desired column
317
318RETURNS:
319 Integer value of the new column. (If current >= target,
320 no action is taken, and current is returned.
321
322GLOBALS:
323 None
324
325CALLS:
326 write (sys)
327
328CALLED BY:
329 dump_line
330
331HISTORY:
332 initial coding November 1976 D A Willcox of CAC
333
334*/\f
335int pad_output (current, target)/* writes tabs and blanks (if necessary) to
336 get the current output position up to
337 the target column */
338int current; /* the current column value */
339int target; /* position we want it at */
340{
341 register int curr; /* internal column pointer */
342 register char *p; /* pointer into buffer of characters to be written */
343 char pobuf[256]; /* pad characters are stored here before writing */
344 register int tcur;
345
346 if (current >= target)
347 return (current); /* line is already long enough */
348
349 curr = current;
350 p = pobuf;
351 while (curr < target) {
352 if ((tcur = ((curr - 1) & tabmask) + tabsize + 1) <= target){
353 *p++ = '\t'; /* put a tab into buffer */
354 curr = tcur;
355 }
356 else {
357 while (curr++ < target)
358 *p++ = ' '; /* pad with final blanks */
359 }
360 }
361
362 write (output, pobuf, p - pobuf); /* write the characters we saved */
363 return (target);
364};
365\f/*
366
367 Copyright (C) 1976
368 by the
369 Board of Trustees
370 of the
371 University of Illinois
372
373 All rights reserved
374
375
376NAME:
377 count_spaces
378
379FUNCTION:
380 Find out where printing of a given string will leave the current
381 character position on output.
382
383ALGORITHM:
384 Run thru input string and add appropriate values to current position.
385
386PARAMETERS:
387 current integer The current line character position
388 buffer ptr to character Pointer to input string
389
390RETURNS:
391 Integer value of position after printing "buffer" starting in
392 column "current".
393
394GLOBALS:
395 None
396
397CALLS:
398 None
399
400CALLED BY:
401 pr_comment
402
403HISTORY:
404 initial coding November 1976 D A Willcox of CAC
405
406*/\f
407int count_spaces (current, buffer)
408 /* this routine figures out where the
409 character position will be after
410 printing the text in buffer starting at
411 column "current" */
412int current;
413char *buffer;
414{
415 register char *buf; /* used to look thru buffer */
416 register int cur; /* current character counter */
417
418 cur = current;
419
420 for (buf = buffer; *buf != '\0'; ++buf) {
421 switch (*buf) {
422
423 case '\n':
424 case 014: /* form feed */
425 cur = 1;
426 break;
427
428 case '\t':
429 cur = ((cur - 1) & tabmask) + tabsize + 1;
430 break;
431
432 case '\b': /* this is a backspace */
433 --cur;
434 break;
435
436 default:
437 ++cur;
438 break;
439 } /* end of switch */
440 } /* end of for loop */
441
442 return (cur);
443};
444\f/*
445
446 Copyright (C) 1976
447 by the
448 Board of Trustees
449 of the
450 University of Illinois
451
452 All rights reserved
453
454
455NAME:
456 eqin
457
458FUNCTION:
459 Returns true if the first arg matches the beginning of the second arg.
460
461ALGORITHM:
462 Trivial
463
464PARAMETERS:
465 str1 pointer to character
466 str2 pointer to character
467
468RETURNS:
469 1 if first string matches start of second string
470 0 otherwise
471
472GLOBALS:
473 None
474
475CALLS:
476 None
477
478CALLED BY:
479 lexi
480 main
481
482HISTORY:
483 initial coding November 1976 by D A Willcox of CAC
484
485*/\f
486eqin (str1, str2)
487char *str1;
488char *str2;
489{
490 register char *s1; /* local pointer into first string */
491 register char *s2; /* local pointer into second string */
492
493 s1 = str1;
494 s2 = str2;
495 while (*s1) { /* compare no further than end of first
496 string */
497 if (*s2 == 0) /* check that second string isn't too short
498 */
499 return (false);
500 if (*s1++ != *s2++)
501 return (false);
502 }
503
504 return (true);
505}
506\f/*
507 Copyright (C) 1976
508 by the
509 Board of Trustees
510 of the
511 University of Illinois
512
513 All rights reserved
514
515NAME:
516 cmp
517
518FUNCTION:
519 Compares two strings
520
521ALGORITHM:
522 Trivial
523
524PARAMETERS:
525 a Pointer to char First string to compare
526 b Pointer to char Second string to compare
527
528RETURNS:
529 -1 if a < b
530 0 if a = b
531 1 if a > b
532
533GLOBALS:
534 None
535
536CALLS:
537 None
538
539CALLED BY:
540 main
541
542HISTORY:
543 1/7/77 D A Willcox of CAC Initial Coding
544*/\f
545int cmp (a, b)
546char *a;
547char *b;
548{
549 register char *ta,
550 *tb;
551
552 ta = a;
553 tb = b;
554
555 while (*ta) {
556 if (*ta > *tb)
557 return (1);
558 if (*ta < *tb)
559 return (-1);
560 ++ta;
561 ++tb;
562 }
563 if (*tb)
564 return (1);
565 else
566 return (0);
567}