source: trunk/minix/commands/indent/io.c@ 20

Last change on this file since 20 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 15.0 KB
Line 
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.
6 *
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.
19 */
20
21#define PUBLIC extern
22#include <ctype.h>
23#include <string.h>
24#include <stdlib.h>
25#include "globs.h"
26#include "proto.h"
27
28
29int comment_open;
30static paren_target;
31
32void 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;
43
44 if (ps.procname[0])
45 {
46 if (troff)
47 {
48 if (comment_open)
49 {
50 comment_open = 0;
51 fprintf(output, ".*/\n");
52 }
53 fprintf(output, ".Pr \"%s\"\n", ps.procname);
54 }
55 ps.ind_level = 0;
56 ps.procname[0] = 0;
57 }
58 if (s_code == e_code && s_lab == e_lab && s_com == e_com)
59 {
60 if (suppress_blanklines > 0)
61 suppress_blanklines--;
62 else
63 {
64 ps.bl_line = true;
65 n_real_blanklines++;
66 }
67 } else if (!inhibit_formatting)
68 {
69 suppress_blanklines = 0;
70 ps.bl_line = false;
71 if (prefix_blankline_requested && not_first_line)
72 if (swallow_opt_bl)
73 {
74 if (n_real_blanklines == 1)
75 n_real_blanklines = 0;
76 } else
77 {
78 if (n_real_blanklines == 0)
79 n_real_blanklines = 1;
80 }
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 */
89
90 if (e_lab != s_lab || e_code != s_code)
91 ++code_lines; /* keep count of lines with
92 code */
93
94
95 if (e_lab != s_lab)
96 { /* print lab, if any */
97 if (comment_open)
98 {
99 comment_open = 0;
100 fprintf(output, ".*/\n");
101 }
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 */
109
110 ps.pcase = false;
111
112 if (s_code != e_code)
113 { /* print code section, if any */
114 register char *p;
115
116 if (comment_open)
117 {
118 comment_open = 0;
119 fprintf(output, ".*/\n");
120 }
121 target_col = code_target();
122 {
123 register i;
124
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);
128 }
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);
136 }
137 if (s_com != e_com)
138 if (troff)
139 {
140 int all_here = 0;
141 register char *p;
142
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)
160 {
161 comment_open = 0;
162 fprintf(output, ".*/\n");
163 }
164 if (comment_open == 0)
165 {
166 if ('a' <= *p && *p <= 'z')
167 *p = *p + 'A' - 'a';
168 if (e_com - p < 50 && all_here == 2)
169 {
170 register char *follow = p;
171 fprintf(output, "\n.nr C! \\w\1");
172 while (follow < e_com)
173 {
174 switch (*follow)
175 {
176 case '\n':
177 putc(' ', output);
178 case 1:
179 break;
180 case '\\':
181 putc('\\', output);
182 default:
183 putc(*follow, output);
184 }
185 follow++;
186 }
187 putc(1, output);
188 }
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);
193 }
194 comment_open = 1 + ps.box_com;
195 while (*p)
196 {
197 if (*p == BACKSLASH)
198 putc(BACKSLASH, output);
199 putc(*p++, output);
200 }
201 } else
202 { /* print comment, if any */
203 register target = ps.com_col;
204 register char *com_st = s_com;
205
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;
222 }
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)
227 {
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);
233 }
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 */
238 }
239 if (ps.use_ff)
240 putc('\014', output);
241 else
242 putc('\n', output);
243inhibit_newline:
244 ++ps.out_lines;
245 if (ps.just_saw_decl == 1 && bl_aft_decl)
246 {
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;
252 }
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;
273}
274
275int code_target()
276{
277 register target_col = ps.ind_size * ps.ind_level + 1;
278
279 if (ps.paren_level)
280 if (!lineup_to_parens)
281 target_col += continuation_indent * ps.paren_level;
282 else
283 {
284 register w;
285 register t = paren_target;
286
287 if ((w = count_spaces(t, s_code) - max_col) > 0
288 && count_spaces(target_col, s_code) <= max_col)
289 {
290 t -= w + 1;
291 if (t > target_col)
292 target_col = t;
293 } else
294 target_col = t;
295 }
296 else if (ps.ind_stmt)
297 target_col += continuation_indent;
298 return target_col;
299}
300
301int label_target()
302{
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;
307}
308
309
310/*
311 * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
312 *
313 * All rights reserved
314 *
315 *
316 * NAME: fill_buffer
317 *
318 * FUNCTION: Reads one block of input into input_buffer
319 *
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
323 *
324 */
325
326void
327fill_buffer()
328{ /* this routine reads stuff
329 from the input */
330 register char *p;
331 register int i;
332 register FILE *f = input;
333
334 if (bp_save != 0)
335 { /* there is a partly filled
336 input buffer left */
337 buf_ptr = bp_save; /* dont read anything, just
338 switch buffers */
339 buf_end = be_save;
340 bp_save = be_save = 0;
341 if (buf_ptr < buf_end)
342 return; /* only return if there is
343 really something in this
344 buffer */
345 }
346 for (p = buf_ptr = in_buffer;;)
347 {
348 if ((i = getc(f)) == EOF)
349 {
350 *p++ = ' ';
351 *p++ = '\n';
352 had_eof = true;
353 break;
354 }
355 *p++ = (char)i;
356 if (i == '\n')
357 break;
358 }
359 buf_end = p;
360 if (p[-2] == '/' && p[-3] == '*')
361 {
362 if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0)
363 fill_buffer(); /* flush indent error message */
364 else
365 {
366 int com = 0;
367
368 p = in_buffer;
369 while (*p == ' ' || *p == '\t')
370 p++;
371 if (*p == '/' && p[1] == '*')
372 {
373 p += 2;
374 while (*p == ' ' || *p == '\t')
375 p++;
376 if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E'
377 && p[4] == 'N' && p[5] == 'T')
378 {
379 p += 6;
380 while (*p == ' ' || *p == '\t')
381 p++;
382 if (*p == '*')
383 com = 1;
384 else if (*p == 'O')
385 if (*++p == 'N')
386 p++, com = 1;
387 else if (*p == 'F' && *++p == 'F')
388 p++, com = 2;
389 while (*p == ' ' || *p == '\t')
390 p++;
391 if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com)
392 {
393 if (s_com != e_com || s_lab != e_lab || s_code != e_code)
394 dump_line();
395 if (!(inhibit_formatting = com - 1))
396 {
397 n_real_blanklines = 0;
398 postfix_blankline_requested = 0;
399 prefix_blankline_requested = 0;
400 suppress_blanklines = 1;
401 }
402 }
403 }
404 }
405 }
406 }
407 if (inhibit_formatting)
408 {
409 p = in_buffer;
410 do
411 putc(*p, output);
412 while (*p++ != '\n');
413 }
414 return;
415}
416
417/*
418 * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
419 *
420 * All rights reserved
421 *
422 *
423 * NAME: pad_output
424 *
425 * FUNCTION: Writes tabs and spaces to move the current column up to the desired
426 * position.
427 *
428 * ALGORITHM: Put tabs and/or blanks into pobuf, then write pobuf.
429 *
430 * PARAMETERS: current integer The current column target
431 * nteger The desired column
432 *
433 * RETURNS: Integer value of the new column. (If current >= target, no action
434 * is taken, and current is returned.
435 *
436 * GLOBALS: None
437 *
438 * CALLS: write (sys)
439 *
440 * CALLED BY: dump_line
441 *
442 * HISTORY: initial coding November 1976 D A Willcox of CAC
443 *
444 */
445
446int pad_output(current, target) /* writes tabs and blanks (if
447 necessary) to get the
448 current output position up
449 to the target column */
450 int current; /* the current column value */
451 int target; /* position we want it at */
452{
453 register int curr; /* internal column pointer */
454 register int tcur;
455
456 if (troff)
457 fprintf(output, "\\h'|%dp'", (target - 1) * 7);
458 else
459 {
460 if (current >= target)
461 return (current); /* line is already long enough */
462 curr = current;
463 while ((tcur = ((curr - 1) & tabmask) + tabsize + 1) <= target)
464 {
465 putc('\t', output);
466 curr = tcur;
467 }
468 while (curr++ < target)
469 putc(' ', output); /* pad with final blanks */
470 }
471 return (target);
472}
473
474/*
475 * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
476 *
477 * All rights reserved
478 *
479 *
480 * NAME: count_spaces
481 *
482 * FUNCTION: Find out where printing of a given string will leave the current
483 * character position on output.
484 *
485 * ALGORITHM: Run thru input string and add appropriate values to current
486 * position.
487 *
488 * RETURNS: Integer value of position after printing "buffer" starting in column
489 * "current".
490 *
491 * HISTORY: initial coding November 1976 D A Willcox of CAC
492 *
493 */
494
495int
496count_spaces(current, buffer)
497/*
498 * this routine figures out where the character position will be after
499 * printing the text in buffer starting at column "current"
500 */
501 int current;
502 char *buffer;
503{
504 register char *buf; /* used to look thru buffer */
505 register int cur; /* current character counter */
506
507 cur = current;
508
509 for (buf = buffer; *buf != '\0'; ++buf)
510 {
511 switch (*buf)
512 {
513
514 case '\n':
515 case 014: /* form feed */
516 cur = 1;
517 break;
518
519 case '\t':
520 cur = ((cur - 1) & tabmask) + tabsize + 1;
521 break;
522
523 case '': /* this is a backspace */
524 --cur;
525 break;
526
527 default:
528 ++cur;
529 break;
530 } /* end of switch */
531 } /* end of for loop */
532 return (cur);
533}
534
535int found_err;
536void diag(level, msg, a, b)
537int level;
538char *msg;
539int a, b;
540{
541 if (level)
542 found_err = 1;
543 if (output == stdout)
544 {
545 fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no);
546 fprintf(stdout, msg, a, b);
547 fprintf(stdout, " */\n");
548 } else
549 {
550 fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no);
551 fprintf(stderr, msg, a, b);
552 fprintf(stderr, "\n");
553 }
554}
555
556void writefdef(f, nm)
557 register struct fstate *f;
558 int nm;
559{
560 fprintf(output, ".ds f%c %s\n.nr s%c %d\n",
561 nm, f->font, nm, f->size);
562}
563
564char *
565chfont(of, nf, s)
566 register struct fstate *of, *nf;
567 char *s;
568{
569 if (of->font[0] != nf->font[0]
570 || of->font[1] != nf->font[1])
571 {
572 *s++ = '\\';
573 *s++ = 'f';
574 if (nf->font[1])
575 {
576 *s++ = '(';
577 *s++ = nf->font[0];
578 *s++ = nf->font[1];
579 } else
580 *s++ = nf->font[0];
581 }
582 if (nf->size != of->size)
583 {
584 *s++ = '\\';
585 *s++ = 's';
586 if (nf->size < of->size)
587 {
588 *s++ = '-';
589 *s++ = (char)'0' + of->size - nf->size;
590 } else
591 {
592 *s++ = '+';
593 *s++ = (char)'0' + nf->size - of->size;
594 }
595 }
596 return s;
597}
598
599
600void parsefont(f, s0)
601 register struct fstate *f;
602 char *s0;
603{
604 register char *s = s0;
605 int sizedelta = 0;
606 memset(f, '\0', sizeof *f);
607 while (*s)
608 {
609 if (isdigit(*s))
610 f->size = f->size * 10 + *s - '0';
611 else if (isupper(*s))
612 if (f->font[0])
613 f->font[1] = *s;
614 else
615 f->font[0] = *s;
616 else if (*s == 'c')
617 f->allcaps = 1;
618 else if (*s == '+')
619 sizedelta++;
620 else if (*s == '-')
621 sizedelta--;
622 else
623 {
624 fprintf(stderr, "indent: bad font specification: %s\n", s0);
625 exit(1);
626 }
627 s++;
628 }
629 if (f->font[0] == 0)
630 f->font[0] = 'R';
631 if (bodyf.size == 0)
632 bodyf.size = 11;
633 if (f->size == 0)
634 f->size = bodyf.size + sizedelta;
635 else if (sizedelta > 0)
636 f->size += bodyf.size;
637 else
638 f->size = bodyf.size - f->size;
639}
Note: See TracBrowser for help on using the repository browser.