1 /****************************************************************
2 Copyright 1990 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[MAX_OUTPUT_SIZE] = "";
102 static char *next_slot = output_buf;
103 static char *string_start;
105 static char *word_start = NULL;
106 static int in_char = 0;
107 static int cursor_pos = 0;
110 adjust_pointer_in_string(pointer)
111 register char *pointer;
113 register char *s, *s1, *se, *s0;
115 /* arrange not to break \002 */
116 s1 = string_start ? string_start : output_buf;
117 for(s = s1; s < pointer; s++) {
124 if (*s < '0' || *s > '7')
127 if (*s < '0' || *s > '7')
135 /* isident -- true iff character could belong to a unit. C allows
136 letters, numbers and underscores in identifiers. This also doubles as
137 a check for numeric constants, since we include the decimal point and
138 minus sign. The minus has to be here, since the constant "10e-2"
139 cannot be broken up. The '.' also prevents structure references from
140 being broken, which is a quite acceptable side effect */
142 #define isident(x) (Tr[x] & 1)
143 #define isntident(x) (!Tr[x])
145 int ind_printf (use_indent, fp, a, b, c, d, e, f, g)
149 long b, c, d, e, f, g;
151 extern int max_line_len;
153 extern char tr_tab[]; /* in output.c */
154 register char *Tr = tr_tab;
156 static int extra_indent, last_indent, set_cursor = 1;
158 cursor_pos += indent - last_indent;
159 last_indent = indent;
160 sprintf (next_slot, a, b, c, d, e, f, g);
163 fprintf (fp,"%s", next_slot);
165 } /* if fp != c_file */
170 /* The for loop will parse one output line */
173 ind = indent <= MAX_INDENT
175 : MIN_INDENT + indent % (MAX_INDENT - MIN_INDENT);
176 cursor_pos = ind + extra_indent;
180 for (pointer = next_slot; *pointer && *pointer != '\n' &&
181 cursor_pos <= max_line_len; pointer++)
184 for (pointer = next_slot; *pointer && *pointer != '\n' &&
185 cursor_pos <= max_line_len; pointer++) {
187 /* Update state variables here */
191 if (!in_char && !in_comment)
192 /* Ignore double quotes in char constants */
193 string_start = word_start = pointer;
197 word_start = in_char ? NULL : pointer;
208 cursor_pos = 8 * ((cursor_pos + 8) / 8) - 1;
215 /* HACK Assumes that all characters in an atomic C token will be written
216 at the same time. Must check for tokens first, since '-' is considered
217 part of an identifier; checking isident first would mean breaking up "->" */
219 if (!word_start && isident(*(unsigned char *)pointer))
220 word_start = pointer;
221 else if (word_start && isntident(*(unsigned char *)pointer))
227 } /* for pointer = next_slot */
228 if (*pointer == '\0') {
230 /* The output line is not complete, so break out and don't output
231 anything. The current line fragment will be stored in the buffer */
236 char *safe_strncpy ();
238 int in_string0 = in_string;
240 /* If the line was too long, move pointer back to the character before
241 the current word. This allows line breaking on word boundaries. Make
242 sure that 80 character comment lines get broken up somehow. We assume
243 that any non-string 80 character identifier must be in a comment.
246 if (word_start && *pointer != '\n' && word_start > output_buf)
248 if (string_start && pointer - string_start < 5)
249 pointer = string_start - 1;
251 pointer = adjust_pointer_in_string(pointer);
254 else if (word_start == string_start) {
255 pointer = adjust_pointer_in_string(next_slot);
260 pointer = word_start - 1;
261 else if (cursor_pos > max_line_len) {
262 extern char *strchr();
264 pointer = adjust_pointer_in_string(pointer);
265 else if (strchr("&*+-/<=>|", *pointer)
266 && strchr("!%&*+-/<=>^|", pointer[-1])) {
268 if (strchr("<>", *pointer)) /* <<=, >>= */
274 last_char = *pointer;
275 write_indent(fp, use_indent, extra_indent, output_buf, pointer);
276 next_slot = output_buf;
277 if (in_string && !string_start && Ansi == 1 && last_char != '\n')
279 (void) safe_strncpy (next_slot, pointer + 1, sizeof(output_buf)-1);
282 /* insert a line break */
284 if (last_char == '\n') {
286 last_was_newline = 0;
288 last_was_newline = 1;
293 extra_indent = TOO_LONG_INDENT;
294 if (in_string && !string_start) {
298 last_was_newline = 1;
302 last_was_newline = 0;
304 in_string = in_string0;
308 last_was_newline = 1;
310 } /* if *pointer != '\n' */
312 if (in_string && Ansi != 1 && !string_start)
317 string_start = word_start = NULL;
321 } while (*next_slot);