packages: don't put oss on cd.
[minix.git] / commands / indent / io.c
blob67a2781fbad61919b8a7496d7028781554337174
1 /**
2 * Copyright (c) 1985 Sun Microsystems, Inc.
3 * Copyright (c) 1980 The Regents of the University of California.
4 * Copyright (c) 1976 Board of Trustees of the University of Illinois.
5 * All rights reserved.
7 * Redistribution and use in source and binary forms are permitted
8 * provided that the above copyright notice and this paragraph are
9 * duplicated in all such forms and that any documentation,
10 * advertising materials, and other materials related to such
11 * distribution and use acknowledge that the software was developed
12 * by the University of California, Berkeley, the University of Illinois,
13 * Urbana, and Sun Microsystems, Inc. The name of either University
14 * or Sun Microsystems may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 #define PUBLIC extern
22 #include <ctype.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include "globs.h"
26 #include "proto.h"
29 int comment_open;
30 static paren_target;
32 void dump_line()
33 { /* dump_line is the routine
34 that actually effects the
35 printing of the new source.
36 It prints the label section,
37 followed by the code section
38 with the appropriate nesting
39 level, followed by any
40 comments */
41 register int cur_col, target_col;
42 static not_first_line;
44 if (ps.procname[0])
46 if (troff)
48 if (comment_open)
50 comment_open = 0;
51 fprintf(output, ".*/\n");
53 fprintf(output, ".Pr \"%s\"\n", ps.procname);
55 ps.ind_level = 0;
56 ps.procname[0] = 0;
58 if (s_code == e_code && s_lab == e_lab && s_com == e_com)
60 if (suppress_blanklines > 0)
61 suppress_blanklines--;
62 else
64 ps.bl_line = true;
65 n_real_blanklines++;
67 } else if (!inhibit_formatting)
69 suppress_blanklines = 0;
70 ps.bl_line = false;
71 if (prefix_blankline_requested && not_first_line)
72 if (swallow_opt_bl)
74 if (n_real_blanklines == 1)
75 n_real_blanklines = 0;
76 } else
78 if (n_real_blanklines == 0)
79 n_real_blanklines = 1;
81 while (--n_real_blanklines >= 0)
82 putc('\n', output);
83 n_real_blanklines = 0;
84 if (ps.ind_level == 0)
85 ps.ind_stmt = 0; /* this is a class A kludge.
86 dont do additional statement
87 indentation if we are at
88 bracket level 0 */
90 if (e_lab != s_lab || e_code != s_code)
91 ++code_lines; /* keep count of lines with
92 code */
95 if (e_lab != s_lab)
96 { /* print lab, if any */
97 if (comment_open)
99 comment_open = 0;
100 fprintf(output, ".*/\n");
102 while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
103 e_lab--;
104 cur_col = pad_output(1, label_target());
105 fprintf(output, "%.*s", (int)(e_lab - s_lab), s_lab);
106 cur_col = count_spaces(cur_col, s_lab);
107 } else
108 cur_col = 1; /* there is no label section */
110 ps.pcase = false;
112 if (s_code != e_code)
113 { /* print code section, if any */
114 register char *p;
116 if (comment_open)
118 comment_open = 0;
119 fprintf(output, ".*/\n");
121 target_col = code_target();
123 register i;
125 for (i = 0; i < ps.p_l_follow; i++)
126 if (ps.paren_indents[i] >= 0)
127 ps.paren_indents[i] = -(ps.paren_indents[i] + target_col);
129 cur_col = pad_output(cur_col, target_col);
130 for (p = s_code; p < e_code; p++)
131 if (*p == (char) 0200)
132 fprintf(output, "%d", target_col * 7);
133 else
134 putc(*p, output);
135 cur_col = count_spaces(cur_col, s_code);
137 if (s_com != e_com)
138 if (troff)
140 int all_here = 0;
141 register char *p;
143 if (e_com[-1] == '/' && e_com[-2] == '*')
144 e_com -= 2, all_here++;
145 while (e_com > s_com && e_com[-1] == ' ')
146 e_com--;
147 *e_com = 0;
148 p = s_com;
149 while (*p == ' ')
150 p++;
151 if (p[0] == '/' && p[1] == '*')
152 p += 2, all_here++;
153 else if (p[0] == '*')
154 p += p[1] == '/' ? 2 : 1;
155 while (*p == ' ')
156 p++;
157 if (*p == 0)
158 goto inhibit_newline;
159 if (comment_open < 2 && ps.box_com)
161 comment_open = 0;
162 fprintf(output, ".*/\n");
164 if (comment_open == 0)
166 if ('a' <= *p && *p <= 'z')
167 *p = *p + 'A' - 'a';
168 if (e_com - p < 50 && all_here == 2)
170 register char *follow = p;
171 fprintf(output, "\n.nr C! \\w\1");
172 while (follow < e_com)
174 switch (*follow)
176 case '\n':
177 putc(' ', output);
178 case 1:
179 break;
180 case '\\':
181 putc('\\', output);
182 default:
183 putc(*follow, output);
185 follow++;
187 putc(1, output);
189 fprintf(output, "\n./* %dp %d %dp\n",
190 ps.com_col * 7,
191 (s_code != e_code || s_lab != e_lab) - ps.box_com,
192 target_col * 7);
194 comment_open = 1 + ps.box_com;
195 while (*p)
197 if (*p == BACKSLASH)
198 putc(BACKSLASH, output);
199 putc(*p++, output);
201 } else
202 { /* print comment, if any */
203 register target = ps.com_col;
204 register char *com_st = s_com;
206 target += ps.comment_delta;
207 while (*com_st == '\t')
208 com_st++, target += 8; /* ? */
209 while (target <= 0)
210 if (*com_st == ' ')
211 target++, com_st++;
212 else if (*com_st == '\t')
213 target = ((target - 1) & ~7) + 9, com_st++;
214 else
215 target = 1;
216 if (cur_col > target)
217 { /* if comment cant fit on this
218 line, put it on next line */
219 putc('\n', output);
220 cur_col = 1;
221 ++ps.out_lines;
223 while (e_com > com_st && isspace(e_com[-1]))
224 e_com--;
225 cur_col = pad_output(cur_col, target);
226 if (!ps.box_com)
228 if (star_comment_cont && (com_st[1] != '*' || e_com <= com_st + 1))
229 if (com_st[1] == ' ' && com_st[0] == ' ' && e_com > com_st + 1)
230 com_st[1] = '*';
231 else
232 fwrite(" * ", com_st[0] == '\t' ? 2 : com_st[0] == '*' ? 1 : 3, 1, output);
234 fwrite(com_st, (int)(e_com - com_st), 1, output);
235 ps.comment_delta = ps.n_comment_delta;
236 cur_col = count_spaces(cur_col, com_st);
237 ++ps.com_lines; /* count lines with comments */
239 if (ps.use_ff)
240 putc('\014', output);
241 else
242 putc('\n', output);
243 inhibit_newline:
244 ++ps.out_lines;
245 if (ps.just_saw_decl == 1 && bl_aft_decl)
247 prefix_blankline_requested = 1;
248 ps.just_saw_decl = 0;
249 } else
250 prefix_blankline_requested = postfix_blankline_requested;
251 postfix_blankline_requested = 0;
253 ps.decl_on_line = ps.in_decl; /* if we are in the middle of a
254 declaration, remember that
255 fact for proper comment
256 indentation */
257 ps.ind_stmt = ps.in_stmt & ~ps.in_decl; /* next line should be
258 indented if we have
259 not completed this
260 stmt and if we are
261 not in the middle of
262 a declaration */
263 ps.use_ff = false;
264 ps.dumped_decl_indent = 0;
265 *(e_lab = s_lab) = '\0'; /* reset buffers */
266 *(e_code = s_code) = '\0';
267 *(e_com = s_com) = '\0';
268 ps.ind_level = ps.i_l_follow;
269 ps.paren_level = ps.p_l_follow;
270 paren_target = -ps.paren_indents[ps.paren_level - 1];
271 not_first_line = 1;
272 return;
275 int code_target()
277 register target_col = ps.ind_size * ps.ind_level + 1;
279 if (ps.paren_level)
280 if (!lineup_to_parens)
281 target_col += continuation_indent * ps.paren_level;
282 else
284 register w;
285 register t = paren_target;
287 if ((w = count_spaces(t, s_code) - max_col) > 0
288 && count_spaces(target_col, s_code) <= max_col)
290 t -= w + 1;
291 if (t > target_col)
292 target_col = t;
293 } else
294 target_col = t;
296 else if (ps.ind_stmt)
297 target_col += continuation_indent;
298 return target_col;
301 int label_target()
303 return
304 ps.pcase ? (int) (case_ind * ps.ind_size) + 1
305 : *s_lab == '#' ? 1
306 : ps.ind_size * (ps.ind_level - label_offset) + 1;
311 * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
313 * All rights reserved
316 * NAME: fill_buffer
318 * FUNCTION: Reads one block of input into input_buffer
320 * HISTORY: initial coding November 1976 D A Willcox of CAC 1/7/77 A
321 * Willcox of CAC Added check for switch back to partly full input
322 * buffer from temporary buffer
324 */\f
325 void
326 fill_buffer()
327 { /* this routine reads stuff
328 from the input */
329 register char *p;
330 register int i;
331 register FILE *f = input;
333 if (bp_save != 0)
334 { /* there is a partly filled
335 input buffer left */
336 buf_ptr = bp_save; /* dont read anything, just
337 switch buffers */
338 buf_end = be_save;
339 bp_save = be_save = 0;
340 if (buf_ptr < buf_end)
341 return; /* only return if there is
342 really something in this
343 buffer */
345 for (p = buf_ptr = in_buffer;;)
347 if ((i = getc(f)) == EOF)
349 *p++ = ' ';
350 *p++ = '\n';
351 had_eof = true;
352 break;
354 *p++ = (char)i;
355 if (i == '\n')
356 break;
358 buf_end = p;
359 if (p[-2] == '/' && p[-3] == '*')
361 if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0)
362 fill_buffer(); /* flush indent error message */
363 else
365 int com = 0;
367 p = in_buffer;
368 while (*p == ' ' || *p == '\t')
369 p++;
370 if (*p == '/' && p[1] == '*')
372 p += 2;
373 while (*p == ' ' || *p == '\t')
374 p++;
375 if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E'
376 && p[4] == 'N' && p[5] == 'T')
378 p += 6;
379 while (*p == ' ' || *p == '\t')
380 p++;
381 if (*p == '*')
382 com = 1;
383 else if (*p == 'O')
384 if (*++p == 'N')
385 p++, com = 1;
386 else if (*p == 'F' && *++p == 'F')
387 p++, com = 2;
388 while (*p == ' ' || *p == '\t')
389 p++;
390 if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com)
392 if (s_com != e_com || s_lab != e_lab || s_code != e_code)
393 dump_line();
394 if (!(inhibit_formatting = com - 1))
396 n_real_blanklines = 0;
397 postfix_blankline_requested = 0;
398 prefix_blankline_requested = 0;
399 suppress_blanklines = 1;
406 if (inhibit_formatting)
408 p = in_buffer;
410 putc(*p, output);
411 while (*p++ != '\n');
413 return;
417 * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
419 * All rights reserved
422 * NAME: pad_output
424 * FUNCTION: Writes tabs and spaces to move the current column up to the desired
425 * position.
427 * ALGORITHM: Put tabs and/or blanks into pobuf, then write pobuf.
429 * PARAMETERS: current integer The current column target
430 * nteger The desired column
432 * RETURNS: Integer value of the new column. (If current >= target, no action
433 * is taken, and current is returned.
435 * GLOBALS: None
437 * CALLS: write (sys)
439 * CALLED BY: dump_line
441 * HISTORY: initial coding November 1976 D A Willcox of CAC
443 */\f
444 int pad_output(current, target) /* writes tabs and blanks (if
445 necessary) to get the
446 current output position up
447 to the target column */
448 int current; /* the current column value */
449 int target; /* position we want it at */
451 register int curr; /* internal column pointer */
452 register int tcur;
454 if (troff)
455 fprintf(output, "\\h'|%dp'", (target - 1) * 7);
456 else
458 if (current >= target)
459 return (current); /* line is already long enough */
460 curr = current;
461 while ((tcur = ((curr - 1) & tabmask) + tabsize + 1) <= target)
463 putc('\t', output);
464 curr = tcur;
466 while (curr++ < target)
467 putc(' ', output); /* pad with final blanks */
469 return (target);
473 * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
475 * All rights reserved
478 * NAME: count_spaces
480 * FUNCTION: Find out where printing of a given string will leave the current
481 * character position on output.
483 * ALGORITHM: Run thru input string and add appropriate values to current
484 * position.
486 * RETURNS: Integer value of position after printing "buffer" starting in column
487 * "current".
489 * HISTORY: initial coding November 1976 D A Willcox of CAC
491 */\f
493 count_spaces(current, buffer)
495 * this routine figures out where the character position will be after
496 * printing the text in buffer starting at column "current"
498 int current;
499 char *buffer;
501 register char *buf; /* used to look thru buffer */
502 register int cur; /* current character counter */
504 cur = current;
506 for (buf = buffer; *buf != '\0'; ++buf)
508 switch (*buf)
511 case '\n':
512 case 014: /* form feed */
513 cur = 1;
514 break;
516 case '\t':
517 cur = ((cur - 1) & tabmask) + tabsize + 1;
518 break;
520 case '\b': /* this is a backspace */
521 --cur;
522 break;
524 default:
525 ++cur;
526 break;
527 } /* end of switch */
528 } /* end of for loop */
529 return (cur);
532 int found_err;
533 void diag(level, msg, a, b)
534 int level;
535 char *msg;
536 int a, b;
538 if (level)
539 found_err = 1;
540 if (output == stdout)
542 fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no);
543 fprintf(stdout, msg, a, b);
544 fprintf(stdout, " */\n");
545 } else
547 fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no);
548 fprintf(stderr, msg, a, b);
549 fprintf(stderr, "\n");
553 void writefdef(f, nm)
554 register struct fstate *f;
555 int nm;
557 fprintf(output, ".ds f%c %s\n.nr s%c %d\n",
558 nm, f->font, nm, f->size);
561 char *
562 chfont(of, nf, s)
563 register struct fstate *of, *nf;
564 char *s;
566 if (of->font[0] != nf->font[0]
567 || of->font[1] != nf->font[1])
569 *s++ = '\\';
570 *s++ = 'f';
571 if (nf->font[1])
573 *s++ = '(';
574 *s++ = nf->font[0];
575 *s++ = nf->font[1];
576 } else
577 *s++ = nf->font[0];
579 if (nf->size != of->size)
581 *s++ = '\\';
582 *s++ = 's';
583 if (nf->size < of->size)
585 *s++ = '-';
586 *s++ = (char)'0' + of->size - nf->size;
587 } else
589 *s++ = '+';
590 *s++ = (char)'0' + nf->size - of->size;
593 return s;
597 void parsefont(f, s0)
598 register struct fstate *f;
599 char *s0;
601 register char *s = s0;
602 int sizedelta = 0;
603 memset(f, '\0', sizeof *f);
604 while (*s)
606 if (isdigit(*s))
607 f->size = f->size * 10 + *s - '0';
608 else if (isupper(*s))
609 if (f->font[0])
610 f->font[1] = *s;
611 else
612 f->font[0] = *s;
613 else if (*s == 'c')
614 f->allcaps = 1;
615 else if (*s == '+')
616 sizedelta++;
617 else if (*s == '-')
618 sizedelta--;
619 else
621 fprintf(stderr, "indent: bad font specification: %s\n", s0);
622 exit(1);
624 s++;
626 if (f->font[0] == 0)
627 f->font[0] = 'R';
628 if (bodyf.size == 0)
629 bodyf.size = 11;
630 if (f->size == 0)
631 f->size = bodyf.size + sizedelta;
632 else if (sizedelta > 0)
633 f->size += bodyf.size;
634 else
635 f->size = bodyf.size - f->size;