Commit | Line | Data |
---|---|---|
87ba9e01 KM |
1 | static 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 | ||
14 | FILE NAME: | |
15 | io.c | |
16 | ||
17 | PURPOSE: | |
18 | Contains routines to handle i/o related stuff for indent. | |
19 | ||
20 | GLOBALS: | |
21 | None | |
22 | ||
23 | FUNCTIONS: | |
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 | ||
43 | NAME: | |
44 | dump_line | |
45 | ||
46 | FUNCTION: | |
47 | Does the actual printing of the stored up line | |
48 | ||
49 | ALGORITHM: | |
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 | ||
63 | PARAMETERS: | |
64 | None | |
65 | ||
66 | RETURNS: | |
67 | Nothing | |
68 | ||
69 | GLOBALS: | |
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 | ||
100 | CALLS: | |
101 | pad_output | |
102 | printf (lib) | |
103 | write (lib) | |
104 | ||
105 | CALLED BY: | |
106 | main | |
107 | pr_comment | |
108 | ||
109 | HISTORY: | |
110 | initial coding November 1976 D A Willcox of CAC | |
111 | ||
112 | */\f | |
113 | #include "indent_globs.h"; | |
114 | ||
115 | ||
116 | ||
117 | int ff = 014; /* used to write a form feed */ | |
118 | ||
119 | ||
120 | dump_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 | ||
227 | NAME: | |
228 | fill_buffer | |
229 | ||
230 | FUNCTION: | |
231 | Reads one block of input into input_buffer | |
232 | ||
233 | ALGORITHM: | |
234 | Trivial | |
235 | ||
236 | PARAMETERS: | |
237 | None | |
238 | ||
239 | RETURNS: | |
240 | Nothing | |
241 | ||
242 | GLOBALS: | |
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 | ||
249 | CALLS: | |
250 | read (lib) | |
251 | ||
252 | CALLED BY: | |
253 | lexi | |
254 | main | |
255 | pr_comment | |
256 | ||
257 | HISTORY: | |
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 | |
264 | int 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 | ||
304 | NAME: | |
305 | pad_output | |
306 | ||
307 | FUNCTION: | |
308 | Writes tabs and spaces to move the current column up to the | |
309 | desired position. | |
310 | ||
311 | ALGORITHM: | |
312 | Put tabs and/or blanks into pobuf, then write pobuf. | |
313 | ||
314 | PARAMETERS: | |
315 | current integer The current column | |
316 | target integer The desired column | |
317 | ||
318 | RETURNS: | |
319 | Integer value of the new column. (If current >= target, | |
320 | no action is taken, and current is returned. | |
321 | ||
322 | GLOBALS: | |
323 | None | |
324 | ||
325 | CALLS: | |
326 | write (sys) | |
327 | ||
328 | CALLED BY: | |
329 | dump_line | |
330 | ||
331 | HISTORY: | |
332 | initial coding November 1976 D A Willcox of CAC | |
333 | ||
334 | */\f | |
335 | int pad_output (current, target)/* writes tabs and blanks (if necessary) to | |
336 | get the current output position up to | |
337 | the target column */ | |
338 | int current; /* the current column value */ | |
339 | int 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 | ||
376 | NAME: | |
377 | count_spaces | |
378 | ||
379 | FUNCTION: | |
380 | Find out where printing of a given string will leave the current | |
381 | character position on output. | |
382 | ||
383 | ALGORITHM: | |
384 | Run thru input string and add appropriate values to current position. | |
385 | ||
386 | PARAMETERS: | |
387 | current integer The current line character position | |
388 | buffer ptr to character Pointer to input string | |
389 | ||
390 | RETURNS: | |
391 | Integer value of position after printing "buffer" starting in | |
392 | column "current". | |
393 | ||
394 | GLOBALS: | |
395 | None | |
396 | ||
397 | CALLS: | |
398 | None | |
399 | ||
400 | CALLED BY: | |
401 | pr_comment | |
402 | ||
403 | HISTORY: | |
404 | initial coding November 1976 D A Willcox of CAC | |
405 | ||
406 | */\f | |
407 | int 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" */ | |
412 | int current; | |
413 | char *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 | ||
455 | NAME: | |
456 | eqin | |
457 | ||
458 | FUNCTION: | |
459 | Returns true if the first arg matches the beginning of the second arg. | |
460 | ||
461 | ALGORITHM: | |
462 | Trivial | |
463 | ||
464 | PARAMETERS: | |
465 | str1 pointer to character | |
466 | str2 pointer to character | |
467 | ||
468 | RETURNS: | |
469 | 1 if first string matches start of second string | |
470 | 0 otherwise | |
471 | ||
472 | GLOBALS: | |
473 | None | |
474 | ||
475 | CALLS: | |
476 | None | |
477 | ||
478 | CALLED BY: | |
479 | lexi | |
480 | main | |
481 | ||
482 | HISTORY: | |
483 | initial coding November 1976 by D A Willcox of CAC | |
484 | ||
485 | */\f | |
486 | eqin (str1, str2) | |
487 | char *str1; | |
488 | char *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 | ||
515 | NAME: | |
516 | cmp | |
517 | ||
518 | FUNCTION: | |
519 | Compares two strings | |
520 | ||
521 | ALGORITHM: | |
522 | Trivial | |
523 | ||
524 | PARAMETERS: | |
525 | a Pointer to char First string to compare | |
526 | b Pointer to char Second string to compare | |
527 | ||
528 | RETURNS: | |
529 | -1 if a < b | |
530 | 0 if a = b | |
531 | 1 if a > b | |
532 | ||
533 | GLOBALS: | |
534 | None | |
535 | ||
536 | CALLS: | |
537 | None | |
538 | ||
539 | CALLED BY: | |
540 | main | |
541 | ||
542 | HISTORY: | |
543 | 1/7/77 D A Willcox of CAC Initial Coding | |
544 | */\f | |
545 | int cmp (a, b) | |
546 | char *a; | |
547 | char *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 | } |