| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: io.c,v 1.27 2021/03/08 22:28:31 rillig Exp $ */ | | 1 | /* $NetBSD: io.c,v 1.28 2021/03/12 19:11:29 rillig Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * SPDX-License-Identifier: BSD-4-Clause | | 4 | * SPDX-License-Identifier: BSD-4-Clause |
5 | * | | 5 | * |
6 | * Copyright (c) 1985 Sun Microsystems, Inc. | | 6 | * Copyright (c) 1985 Sun Microsystems, Inc. |
7 | * Copyright (c) 1980, 1993 | | 7 | * Copyright (c) 1980, 1993 |
8 | * The Regents of the University of California. All rights reserved. | | 8 | * The Regents of the University of California. All rights reserved. |
9 | * All rights reserved. | | 9 | * All rights reserved. |
10 | * | | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | | 11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions | | 12 | * modification, are permitted provided that the following conditions |
13 | * are met: | | 13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright | | 14 | * 1. Redistributions of source code must retain the above copyright |
| @@ -36,45 +36,69 @@ | | | @@ -36,45 +36,69 @@ |
36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
37 | * SUCH DAMAGE. | | 37 | * SUCH DAMAGE. |
38 | */ | | 38 | */ |
39 | | | 39 | |
40 | #if 0 | | 40 | #if 0 |
41 | #ifndef lint | | 41 | #ifndef lint |
42 | static char sccsid[] = "@(#)io.c 8.1 (Berkeley) 6/6/93"; | | 42 | static char sccsid[] = "@(#)io.c 8.1 (Berkeley) 6/6/93"; |
43 | #endif /* not lint */ | | 43 | #endif /* not lint */ |
44 | #endif | | 44 | #endif |
45 | | | 45 | |
46 | #include <sys/cdefs.h> | | 46 | #include <sys/cdefs.h> |
47 | #ifndef lint | | 47 | #ifndef lint |
48 | #if defined(__NetBSD__) | | 48 | #if defined(__NetBSD__) |
49 | __RCSID("$NetBSD: io.c,v 1.27 2021/03/08 22:28:31 rillig Exp $"); | | 49 | __RCSID("$NetBSD: io.c,v 1.28 2021/03/12 19:11:29 rillig Exp $"); |
50 | #elif defined(__FreeBSD__) | | 50 | #elif defined(__FreeBSD__) |
51 | __FBSDID("$FreeBSD: head/usr.bin/indent/io.c 334927 2018-06-10 16:44:18Z pstef $"); | | 51 | __FBSDID("$FreeBSD: head/usr.bin/indent/io.c 334927 2018-06-10 16:44:18Z pstef $"); |
52 | #endif | | 52 | #endif |
53 | #endif | | 53 | #endif |
54 | | | 54 | |
55 | #include <ctype.h> | | 55 | #include <ctype.h> |
56 | #include <err.h> | | 56 | #include <err.h> |
57 | #include <stdio.h> | | 57 | #include <stdio.h> |
58 | #include <stdlib.h> | | 58 | #include <stdlib.h> |
59 | #include <string.h> | | 59 | #include <string.h> |
60 | #include <stdarg.h> | | 60 | #include <stdarg.h> |
61 | | | 61 | |
62 | #include "indent.h" | | 62 | #include "indent.h" |
63 | | | 63 | |
64 | int comment_open; | | 64 | int comment_open; |
65 | static int paren_target; | | 65 | static int paren_target; |
66 | static int pad_output(int current, int target); | | 66 | static int pad_output(int current, int target); |
67 | | | 67 | |
| | | 68 | static void |
| | | 69 | output_char(char ch) |
| | | 70 | { |
| | | 71 | fputc(ch, output); |
| | | 72 | } |
| | | 73 | |
| | | 74 | static void |
| | | 75 | output_range(const char *s, const char *e) |
| | | 76 | { |
| | | 77 | fwrite(s, 1, (size_t)(e - s), output); |
| | | 78 | } |
| | | 79 | |
| | | 80 | static void |
| | | 81 | output_string(const char *s) |
| | | 82 | { |
| | | 83 | output_range(s, s + strlen(s)); |
| | | 84 | } |
| | | 85 | |
| | | 86 | static void |
| | | 87 | output_int(int i) |
| | | 88 | { |
| | | 89 | fprintf(output, "%d", i); |
| | | 90 | } |
| | | 91 | |
68 | /* | | 92 | /* |
69 | * dump_line is the routine that actually effects the printing of the new | | 93 | * dump_line is the routine that actually effects the printing of the new |
70 | * source. It prints the label section, followed by the code section with | | 94 | * source. It prints the label section, followed by the code section with |
71 | * the appropriate nesting level, followed by any comments. | | 95 | * the appropriate nesting level, followed by any comments. |
72 | */ | | 96 | */ |
73 | void | | 97 | void |
74 | dump_line(void) | | 98 | dump_line(void) |
75 | { | | 99 | { |
76 | int cur_col, target_col; | | 100 | int cur_col, target_col; |
77 | static int not_first_line; | | 101 | static int not_first_line; |
78 | | | 102 | |
79 | if (ps.procname[0]) { | | 103 | if (ps.procname[0]) { |
80 | ps.ind_level = 0; | | 104 | ps.ind_level = 0; |
| @@ -92,137 +116,144 @@ dump_line(void) | | | @@ -92,137 +116,144 @@ dump_line(void) |
92 | suppress_blanklines = 0; | | 116 | suppress_blanklines = 0; |
93 | ps.bl_line = false; | | 117 | ps.bl_line = false; |
94 | if (prefix_blankline_requested && not_first_line) { | | 118 | if (prefix_blankline_requested && not_first_line) { |
95 | if (opt.swallow_optional_blanklines) { | | 119 | if (opt.swallow_optional_blanklines) { |
96 | if (n_real_blanklines == 1) | | 120 | if (n_real_blanklines == 1) |
97 | n_real_blanklines = 0; | | 121 | n_real_blanklines = 0; |
98 | } | | 122 | } |
99 | else { | | 123 | else { |
100 | if (n_real_blanklines == 0) | | 124 | if (n_real_blanklines == 0) |
101 | n_real_blanklines = 1; | | 125 | n_real_blanklines = 1; |
102 | } | | 126 | } |
103 | } | | 127 | } |
104 | while (--n_real_blanklines >= 0) | | 128 | while (--n_real_blanklines >= 0) |
105 | putc('\n', output); | | 129 | output_char('\n'); |
106 | n_real_blanklines = 0; | | 130 | n_real_blanklines = 0; |
107 | if (ps.ind_level == 0) | | 131 | if (ps.ind_level == 0) |
108 | ps.ind_stmt = 0; /* this is a class A kludge. dont do | | 132 | ps.ind_stmt = 0; /* this is a class A kludge. dont do |
109 | * additional statement indentation if we are | | 133 | * additional statement indentation if we are |
110 | * at bracket level 0 */ | | 134 | * at bracket level 0 */ |
111 | | | 135 | |
112 | if (e_lab != s_lab || e_code != s_code) | | 136 | if (e_lab != s_lab || e_code != s_code) |
113 | ++code_lines; /* keep count of lines with code */ | | 137 | ++code_lines; /* keep count of lines with code */ |
114 | | | 138 | |
115 | | | 139 | |
116 | if (e_lab != s_lab) { /* print lab, if any */ | | 140 | if (e_lab != s_lab) { /* print lab, if any */ |
117 | if (comment_open) { | | 141 | if (comment_open) { |
118 | comment_open = 0; | | 142 | comment_open = 0; |
119 | fprintf(output, ".*/\n"); | | 143 | output_string(".*/\n"); |
120 | } | | 144 | } |
121 | while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) | | 145 | while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) |
122 | e_lab--; | | 146 | e_lab--; |
123 | *e_lab = '\0'; | | 147 | *e_lab = '\0'; |
124 | cur_col = pad_output(1, compute_label_target()); | | 148 | cur_col = pad_output(1, compute_label_target()); |
125 | if (s_lab[0] == '#' && (strncmp(s_lab, "#else", 5) == 0 | | 149 | if (s_lab[0] == '#' && (strncmp(s_lab, "#else", 5) == 0 |
126 | || strncmp(s_lab, "#endif", 6) == 0)) { | | 150 | || strncmp(s_lab, "#endif", 6) == 0)) { |
127 | char *s = s_lab; | | 151 | char *s = s_lab; |
128 | if (e_lab[-1] == '\n') e_lab--; | | 152 | if (e_lab[-1] == '\n') e_lab--; |
129 | do { | | 153 | do { |
130 | putc(*s++, output); | | 154 | output_char(*s++); |
131 | } while (s < e_lab && 'a' <= *s && *s <= 'z'); | | 155 | } while (s < e_lab && 'a' <= *s && *s <= 'z'); |
132 | while ((*s == ' ' || *s == '\t') && s < e_lab) | | 156 | while ((*s == ' ' || *s == '\t') && s < e_lab) |
133 | s++; | | 157 | s++; |
134 | if (s < e_lab) | | 158 | if (s < e_lab) { |
135 | fprintf(output, s[0]=='/' && s[1]=='*' ? "\t%.*s" : "\t/* %.*s */", | | 159 | if (s[0] == '/' && s[1] == '*') { |
136 | (int)(e_lab - s), s); | | 160 | output_char('\t'); |
137 | } | | 161 | output_range(s, e_lab); |
138 | else fprintf(output, "%.*s", (int)(e_lab - s_lab), s_lab); | | 162 | } else { |
| | | 163 | output_string("\t/* "); |
| | | 164 | output_range(s, e_lab); |
| | | 165 | output_string(" */"); |
| | | 166 | } |
| | | 167 | } |
| | | 168 | } else |
| | | 169 | output_range(s_lab, e_lab); |
139 | cur_col = count_spaces(cur_col, s_lab); | | 170 | cur_col = count_spaces(cur_col, s_lab); |
140 | } | | 171 | } |
141 | else | | 172 | else |
142 | cur_col = 1; /* there is no label section */ | | 173 | cur_col = 1; /* there is no label section */ |
143 | | | 174 | |
144 | ps.pcase = false; | | 175 | ps.pcase = false; |
145 | | | 176 | |
146 | if (s_code != e_code) { /* print code section, if any */ | | 177 | if (s_code != e_code) { /* print code section, if any */ |
147 | char *p; | | 178 | char *p; |
148 | | | 179 | |
149 | if (comment_open) { | | 180 | if (comment_open) { |
150 | comment_open = 0; | | 181 | comment_open = 0; |
151 | fprintf(output, ".*/\n"); | | 182 | output_string(".*/\n"); |
152 | } | | 183 | } |
153 | target_col = compute_code_target(); | | 184 | target_col = compute_code_target(); |
154 | { | | 185 | { |
155 | int i; | | 186 | int i; |
156 | | | 187 | |
157 | for (i = 0; i < ps.p_l_follow; i++) | | 188 | for (i = 0; i < ps.p_l_follow; i++) |
158 | if (ps.paren_indents[i] >= 0) | | 189 | if (ps.paren_indents[i] >= 0) |
159 | ps.paren_indents[i] = -(ps.paren_indents[i] + target_col); | | 190 | ps.paren_indents[i] = -(ps.paren_indents[i] + target_col); |
160 | } | | 191 | } |
161 | cur_col = pad_output(cur_col, target_col); | | 192 | cur_col = pad_output(cur_col, target_col); |
162 | for (p = s_code; p < e_code; p++) | | 193 | for (p = s_code; p < e_code; p++) |
163 | if (*p == (char) 0200) | | 194 | if (*p == (char) 0200) |
164 | fprintf(output, "%d", target_col * 7); | | 195 | output_int(target_col * 7); |
165 | else | | 196 | else |
166 | putc(*p, output); | | 197 | output_char(*p); |
167 | cur_col = count_spaces(cur_col, s_code); | | 198 | cur_col = count_spaces(cur_col, s_code); |
168 | } | | 199 | } |
169 | if (s_com != e_com) { /* print comment, if any */ | | 200 | if (s_com != e_com) { /* print comment, if any */ |
170 | int target = ps.com_col; | | 201 | int target = ps.com_col; |
171 | char *com_st = s_com; | | 202 | char *com_st = s_com; |
172 | | | 203 | |
173 | target += ps.comment_delta; | | 204 | target += ps.comment_delta; |
174 | while (*com_st == '\t') /* consider original indentation in | | 205 | while (*com_st == '\t') /* consider original indentation in |
175 | * case this is a box comment */ | | 206 | * case this is a box comment */ |
176 | com_st++, target += opt.tabsize; | | 207 | com_st++, target += opt.tabsize; |
177 | while (target <= 0) | | 208 | while (target <= 0) |
178 | if (*com_st == ' ') | | 209 | if (*com_st == ' ') |
179 | target++, com_st++; | | 210 | target++, com_st++; |
180 | else if (*com_st == '\t') { | | 211 | else if (*com_st == '\t') { |
181 | target = opt.tabsize * (1 + (target - 1) / opt.tabsize) + 1; | | 212 | target = opt.tabsize * (1 + (target - 1) / opt.tabsize) + 1; |
182 | com_st++; | | 213 | com_st++; |
183 | } | | 214 | } |
184 | else | | 215 | else |
185 | target = 1; | | 216 | target = 1; |
186 | if (cur_col > target) { /* if comment can't fit on this line, | | 217 | if (cur_col > target) { /* if comment can't fit on this line, |
187 | * put it on next line */ | | 218 | * put it on next line */ |
188 | putc('\n', output); | | 219 | output_char('\n'); |
189 | cur_col = 1; | | 220 | cur_col = 1; |
190 | ++ps.out_lines; | | 221 | ++ps.out_lines; |
191 | } | | 222 | } |
192 | while (e_com > com_st && isspace((unsigned char)e_com[-1])) | | 223 | while (e_com > com_st && isspace((unsigned char)e_com[-1])) |
193 | e_com--; | | 224 | e_com--; |
194 | (void)pad_output(cur_col, target); | | 225 | (void)pad_output(cur_col, target); |
195 | fwrite(com_st, e_com - com_st, 1, output); | | 226 | output_range(com_st, e_com); |
196 | ps.comment_delta = ps.n_comment_delta; | | 227 | ps.comment_delta = ps.n_comment_delta; |
197 | ++ps.com_lines; /* count lines with comments */ | | 228 | ++ps.com_lines; /* count lines with comments */ |
198 | } | | 229 | } |
199 | if (ps.use_ff) | | 230 | if (ps.use_ff) |
200 | putc('\014', output); | | 231 | output_char('\014'); |
201 | else | | 232 | else |
202 | putc('\n', output); | | 233 | output_char('\n'); |
203 | ++ps.out_lines; | | 234 | ++ps.out_lines; |
204 | if (ps.just_saw_decl == 1 && opt.blanklines_after_declarations) { | | 235 | if (ps.just_saw_decl == 1 && opt.blanklines_after_declarations) { |
205 | prefix_blankline_requested = 1; | | 236 | prefix_blankline_requested = 1; |
206 | ps.just_saw_decl = 0; | | 237 | ps.just_saw_decl = 0; |
207 | } | | 238 | } |
208 | else | | 239 | else |
209 | prefix_blankline_requested = postfix_blankline_requested; | | 240 | prefix_blankline_requested = postfix_blankline_requested; |
210 | postfix_blankline_requested = 0; | | 241 | postfix_blankline_requested = 0; |
211 | } | | 242 | } |
212 | | | 243 | |
213 | /* keep blank lines after '//' comments */ | | 244 | /* keep blank lines after '//' comments */ |
214 | if (e_com - s_com > 1 && s_com[1] == '/') | | 245 | if (e_com - s_com > 1 && s_com[1] == '/') |
215 | fprintf(output, "%.*s", (int)(e_token - s_token), s_token); | | 246 | output_range(s_token, e_token); |
216 | | | 247 | |
217 | ps.decl_on_line = ps.in_decl; /* if we are in the middle of a | | 248 | ps.decl_on_line = ps.in_decl; /* if we are in the middle of a |
218 | * declaration, remember that fact for | | 249 | * declaration, remember that fact for |
219 | * proper comment indentation */ | | 250 | * proper comment indentation */ |
220 | ps.ind_stmt = ps.in_stmt & ~ps.in_decl; /* next line should be | | 251 | ps.ind_stmt = ps.in_stmt & ~ps.in_decl; /* next line should be |
221 | * indented if we have not | | 252 | * indented if we have not |
222 | * completed this stmt and if | | 253 | * completed this stmt and if |
223 | * we are not in the middle of | | 254 | * we are not in the middle of |
224 | * a declaration */ | | 255 | * a declaration */ |
225 | ps.use_ff = false; | | 256 | ps.use_ff = false; |
226 | ps.dumped_decl_indent = 0; | | 257 | ps.dumped_decl_indent = 0; |
227 | *(e_lab = s_lab) = '\0'; /* reset buffers */ | | 258 | *(e_lab = s_lab) = '\0'; /* reset buffers */ |
228 | *(e_code = s_code) = '\0'; | | 259 | *(e_code = s_code) = '\0'; |
| @@ -361,27 +392,27 @@ fill_buffer(void) | | | @@ -361,27 +392,27 @@ fill_buffer(void) |
361 | n_real_blanklines = 0; | | 392 | n_real_blanklines = 0; |
362 | postfix_blankline_requested = 0; | | 393 | postfix_blankline_requested = 0; |
363 | prefix_blankline_requested = 0; | | 394 | prefix_blankline_requested = 0; |
364 | suppress_blanklines = 1; | | 395 | suppress_blanklines = 1; |
365 | } | | 396 | } |
366 | } | | 397 | } |
367 | } | | 398 | } |
368 | } | | 399 | } |
369 | } | | 400 | } |
370 | } | | 401 | } |
371 | if (inhibit_formatting) { | | 402 | if (inhibit_formatting) { |
372 | p = in_buffer; | | 403 | p = in_buffer; |
373 | do { | | 404 | do { |
374 | putc(*p, output); | | 405 | output_char(*p); |
375 | } while (*p++ != '\n'); | | 406 | } while (*p++ != '\n'); |
376 | } | | 407 | } |
377 | } | | 408 | } |
378 | | | 409 | |
379 | /* | | 410 | /* |
380 | * Copyright (C) 1976 by the Board of Trustees of the University of Illinois | | 411 | * Copyright (C) 1976 by the Board of Trustees of the University of Illinois |
381 | * | | 412 | * |
382 | * All rights reserved | | 413 | * All rights reserved |
383 | * | | 414 | * |
384 | * | | 415 | * |
385 | * NAME: pad_output | | 416 | * NAME: pad_output |
386 | * | | 417 | * |
387 | * FUNCTION: Writes tabs and spaces to move the current column up to the desired | | 418 | * FUNCTION: Writes tabs and spaces to move the current column up to the desired |
| @@ -411,32 +442,32 @@ pad_output(int current, int target) | | | @@ -411,32 +442,32 @@ pad_output(int current, int target) |
411 | * target column */ | | 442 | * target column */ |
412 | /* current: the current column value */ | | 443 | /* current: the current column value */ |
413 | /* target: position we want it at */ | | 444 | /* target: position we want it at */ |
414 | { | | 445 | { |
415 | int curr; /* internal column pointer */ | | 446 | int curr; /* internal column pointer */ |
416 | | | 447 | |
417 | if (current >= target) | | 448 | if (current >= target) |
418 | return current; /* line is already long enough */ | | 449 | return current; /* line is already long enough */ |
419 | curr = current; | | 450 | curr = current; |
420 | if (opt.use_tabs) { | | 451 | if (opt.use_tabs) { |
421 | int tcur; | | 452 | int tcur; |
422 | | | 453 | |
423 | while ((tcur = opt.tabsize * (1 + (curr - 1) / opt.tabsize) + 1) <= target) { | | 454 | while ((tcur = opt.tabsize * (1 + (curr - 1) / opt.tabsize) + 1) <= target) { |
424 | putc('\t', output); | | 455 | output_char('\t'); |
425 | curr = tcur; | | 456 | curr = tcur; |
426 | } | | 457 | } |
427 | } | | 458 | } |
428 | while (curr++ < target) | | 459 | while (curr++ < target) |
429 | putc(' ', output); /* pad with final blanks */ | | 460 | output_char(' '); /* pad with final blanks */ |
430 | | | 461 | |
431 | return target; | | 462 | return target; |
432 | } | | 463 | } |
433 | | | 464 | |
434 | /* | | 465 | /* |
435 | * Copyright (C) 1976 by the Board of Trustees of the University of Illinois | | 466 | * Copyright (C) 1976 by the Board of Trustees of the University of Illinois |
436 | * | | 467 | * |
437 | * All rights reserved | | 468 | * All rights reserved |
438 | * | | 469 | * |
439 | * | | 470 | * |
440 | * NAME: count_spaces | | 471 | * NAME: count_spaces |
441 | * | | 472 | * |
442 | * FUNCTION: Find out where printing of a given string will leave the current | | 473 | * FUNCTION: Find out where printing of a given string will leave the current |