1 /****************************************************************
2 Copyright 1990, 1991 by AT&T Bell Laboratories and Bellcore.
4 Permission to use, copy, modify, and distribute this software
5 and its documentation for any purpose and without fee is hereby
6 granted, provided that the above copyright notice appear in all
7 copies and that both that the copyright notice and this
8 permission notice and warranty disclaimer appear in supporting
9 documentation, and that the names of AT&T Bell Laboratories or
10 Bellcore or any of their entities not be used in advertising or
11 publicity pertaining to distribution of the software without
12 specific, written prior permission.
14 AT&T and Bellcore disclaim all warranties with regard to this
15 software, including all implied warranties of merchantability
16 and fitness. In no event shall AT&T or Bellcore be liable for
17 any special, indirect or consequential damages or any damages
18 whatsoever resulting from loss of use, data or profits, whether
19 in an action of contract, negligence or other tortious action,
20 arising out of or in connection with the use or performance of
22 ****************************************************************/
28 #define TOO_LONG_INDENT (2 * tab_size)
31 static int last_was_newline = 0;
36 write_indent(fp, use_indent, extra_indent, start, end)
38 int use_indent, extra_indent;
43 if (last_was_newline && use_indent) {
44 if (*start == '\n') do {
49 while(*start == '\n');
51 ind = indent <= MAX_INDENT
53 : MIN_INDENT + indent % (MAX_INDENT - MIN_INDENT);
55 tab = ind + extra_indent;
64 } /* if last_was_newline */
72 int margin_printf (fp, a, b, c, d, e, f, g)
75 long b, c, d, e, f, g;
77 ind_printf (0, fp, a, b, c, d, e, f, g);
81 int nice_printf (fp, a, b, c, d, e, f, g)
84 long b, c, d, e, f, g;
86 ind_printf (1, fp, a, b, c, d, e, f, g);
90 #define max_line_len c_output_line_length
91 /* 74Number of characters allowed on an output
92 line. This assumes newlines are handled
93 nicely, i.e. a newline after a full text
94 line on a terminal is ignored */
96 /* output_buf holds the text of the next line to be printed. It gets
97 flushed when a newline is printed. next_slot points to the next
98 available location in the output buffer, i.e. where the next call to
99 nice_printf will have its output stored */
101 static char *output_buf;
102 static char *next_slot;
103 static char *string_start;
105 static char *word_start = NULL;
106 static int cursor_pos = 0;
107 static int In_string = 0;
112 next_slot = output_buf = Alloc(MAX_OUTPUT_SIZE);
113 memset(output_buf, 0, MAX_OUTPUT_SIZE);
117 adjust_pointer_in_string(pointer)
118 register char *pointer;
120 register char *s, *s1, *se, *s0;
122 /* arrange not to break \002 */
123 s1 = string_start ? string_start : output_buf;
124 for(s = s1; s < pointer; s++) {
131 if (*s < '0' || *s > '7')
134 if (*s < '0' || *s > '7')
142 /* ANSI says strcpy's behavior is undefined for overlapping args,
143 * so we roll our own fwd_strcpy: */
147 register char *t, *s;
148 { while(*t++ = *s++); }
150 /* isident -- true iff character could belong to a unit. C allows
151 letters, numbers and underscores in identifiers. This also doubles as
152 a check for numeric constants, since we include the decimal point and
153 minus sign. The minus has to be here, since the constant "10e-2"
154 cannot be broken up. The '.' also prevents structure references from
155 being broken, which is a quite acceptable side effect */
157 #define isident(x) (Tr[x] & 1)
158 #define isntident(x) (!Tr[x])
160 int ind_printf (use_indent, fp, a, b, c, d, e, f, g)
164 long b, c, d, e, f, g;
166 extern int max_line_len;
168 extern char tr_tab[]; /* in output.c */
169 register char *Tr = tr_tab;
171 static int extra_indent, last_indent, set_cursor = 1;
173 cursor_pos += indent - last_indent;
174 last_indent = indent;
175 sprintf (next_slot, a, b, c, d, e, f, g);
178 fprintf (fp,"%s", next_slot);
180 } /* if fp != c_file */
185 /* The for loop will parse one output line */
188 ind = indent <= MAX_INDENT
190 : MIN_INDENT + indent % (MAX_INDENT - MIN_INDENT);
191 cursor_pos = ind + extra_indent;
195 for (pointer = next_slot; *pointer && *pointer != '\n' &&
196 cursor_pos <= max_line_len; pointer++)
199 for (pointer = next_slot; *pointer && *pointer != '\n' &&
200 cursor_pos <= max_line_len; pointer++) {
202 /* Update state variables here */
207 if (++cursor_pos > max_line_len) {
219 else switch (*pointer) {
221 if (cursor_pos + 5 > max_line_len) {
227 string_start = word_start = pointer;
230 if (pointer[1] == '\\')
231 if ((ch = pointer[2]) >= '0' && ch <= '7')
232 for(inc = 3; pointer[inc] != '\''
238 /*debug*/ if (pointer[inc] != '\'')
239 /*debug*/ fatalstr("Bad character constant %.10s",
241 if ((cursor_pos += inc) > max_line_len) {
247 word_start = pointer;
251 cursor_pos = 8 * ((cursor_pos + 8) / 8) - 1;
255 /* HACK Assumes that all characters in an atomic C token will be written
256 at the same time. Must check for tokens first, since '-' is considered
257 part of an identifier; checking isident first would mean breaking up "->" */
259 if (!word_start && isident(*(unsigned char *)pointer))
260 word_start = pointer;
261 else if (word_start && isntident(*(unsigned char *)pointer))
267 } /* for pointer = next_slot */
269 if (*pointer == '\0') {
271 /* The output line is not complete, so break out and don't output
272 anything. The current line fragment will be stored in the buffer */
278 int in_string0 = In_string;
280 /* If the line was too long, move pointer back to the character before
281 the current word. This allows line breaking on word boundaries. Make
282 sure that 80 character comment lines get broken up somehow. We assume
283 that any non-string 80 character identifier must be in a comment.
286 if (word_start && *pointer != '\n' && word_start > output_buf)
288 if (string_start && pointer - string_start < 5)
289 pointer = string_start - 1;
291 pointer = adjust_pointer_in_string(pointer);
294 else if (word_start == string_start
295 && pointer - string_start >= 5) {
296 pointer = adjust_pointer_in_string(next_slot);
301 pointer = word_start - 1;
302 else if (cursor_pos > max_line_len) {
303 extern char *strchr();
305 pointer = adjust_pointer_in_string(pointer);
306 if (string_start && pointer > string_start)
309 else if (strchr("&*+-/<=>|", *pointer)
310 && strchr("!%&*+-/<=>^|", pointer[-1])) {
312 if (strchr("<>", *pointer)) /* <<=, >>= */
318 last_char = *pointer;
319 write_indent(fp, use_indent, extra_indent, output_buf, pointer);
320 next_slot = output_buf;
321 if (In_string && !string_start && Ansi == 1 && last_char != '\n')
323 fwd_strcpy(next_slot, pointer + 1);
325 /* insert a line break */
327 if (last_char == '\n') {
329 last_was_newline = 0;
331 last_was_newline = 1;
336 extra_indent = TOO_LONG_INDENT;
337 if (In_string && !string_start) {
341 last_was_newline = 1;
345 last_was_newline = 0;
347 In_string = in_string0;
351 last_was_newline = 1;
353 } /* if *pointer != '\n' */
355 if (In_string && Ansi != 1 && !string_start)
360 string_start = word_start = NULL;
364 } while (*next_slot);