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