Fri Jun 9 06:36:58 2023 UTC ()
indent: indent multi-line expressions according to parentheses

This reverts the FreeBSD change from 2004-02-12 that had been imported
on 2019-04-04.


(rillig)
diff -r1.9 -r1.10 src/tests/usr.bin/indent/opt_ci.c
diff -r1.9 -r1.10 src/tests/usr.bin/indent/opt_lp.c
diff -r1.32 -r1.33 src/usr.bin/indent/indent.1
diff -r1.204 -r1.205 src/usr.bin/indent/io.c

cvs diff -r1.9 -r1.10 src/tests/usr.bin/indent/opt_ci.c (switch to unified diff)

--- src/tests/usr.bin/indent/opt_ci.c 2023/05/18 05:33:27 1.9
+++ src/tests/usr.bin/indent/opt_ci.c 2023/06/09 06:36:58 1.10
@@ -1,252 +1,247 @@ @@ -1,252 +1,247 @@
1/* $NetBSD: opt_ci.c,v 1.9 2023/05/18 05:33:27 rillig Exp $ */ 1/* $NetBSD: opt_ci.c,v 1.10 2023/06/09 06:36:58 rillig Exp $ */
2 2
3/* 3/*
4 * Tests for the option '-ci', which controls the indentation of continuation 4 * Tests for the option '-ci', which controls the indentation of continuation
5 * lines in statements and declarations, but only inside a function. 5 * lines in statements and declarations, but only inside a function.
6 */ 6 */
7 7
8/* 8/*
9 * Top level expressions with and without parentheses. 9 * Top level expressions with and without parentheses.
10 */ 10 */
11//indent input 11//indent input
12int top_level = 1 + 12int top_level = 1 +
13 2; 13 2;
14int top_level = (1 + 14int top_level = (1 +
15 2 + ( 15 2 + (
16 3)); 16 3));
17//indent end 17//indent end
18 18
19//indent run -ci0 19//indent run -ci0
20int top_level = 1 + 20int top_level = 1 +
212; 212;
22int top_level = (1 + 22int top_level = (1 +
23 2 + ( 23 2 + (
24 3)); 24 3));
25//indent end 25//indent end
26 26
27//indent run-equals-prev-output -ci2 27//indent run-equals-prev-output -ci2
28 28
29//indent run-equals-prev-output -ci4 29//indent run-equals-prev-output -ci4
30 30
31//indent run-equals-prev-output -ci8 31//indent run-equals-prev-output -ci8
32 32
33//indent run -ci0 -nlp 33//indent run -ci0 -nlp
34int top_level = 1 + 34int top_level = 1 +
352; 352;
36int top_level = (1 + 36int top_level = (1 +
37 2 + ( 37 2 + (
38 3)); 38 3));
39//indent end 39//indent end
40 40
41//indent run -ci2 -nlp 41//indent run -ci2 -nlp
42int top_level = 1 + 42int top_level = 1 +
432; 432;
44int top_level = (1 + 44int top_level = (1 +
45 2 + ( 45 2 + (
46 3)); 46 3));
47//indent end 47//indent end
48 48
49/* 49/*
50 * Since '-ci4' is half an indentation level, indent all continuations using 50 * Between 2019-04-04 and 2023-06-09, there was a special rule that prevented
51 * the same level, no matter how many parentheses there are. The rationale for 51 * indentation based on the number of open parentheses, in the case that the
52 * this may have been to prevent that the continuation line has the same 52 * continuation indentation is half an indentation level, maybe to prevent that
53 * indentation as a follow-up statement, such as in 'if' statements. 53 * the continuation line has the same indentation as a follow-up statement,
 54 * such as in 'if' statements. To prevent such ambiguities, see '-eei'.
54 */ 55 */
55//indent run -ci4 -nlp 56//indent run -ci4 -nlp
56int top_level = 1 + 57int top_level = 1 +
572; 582;
58int top_level = (1 + 59int top_level = (1 +
59 2 + ( 60 2 + (
60 3)); 61 3));
61//indent end 62//indent end
62 63
63 64
64/* 65/*
65 * Declarations in functions without parentheses. 66 * Declarations in functions without parentheses.
66 */ 67 */
67//indent input 68//indent input
68int 69int
69sum(int a, int b) 70sum(int a, int b)
70{ 71{
71 return a + 72 return a +
72 b; 73 b;
73 return first + 74 return first +
74 second; 75 second;
75} 76}
76//indent end 77//indent end
77 78
78//indent run -ci0 79//indent run -ci0
79int 80int
80sum(int a, int b) 81sum(int a, int b)
81{ 82{
82 return a + 83 return a +
83 b; 84 b;
84 return first + 85 return first +
85 second; 86 second;
86} 87}
87//indent end 88//indent end
88 89
89//indent run -ci2 90//indent run -ci2
90int 91int
91sum(int a, int b) 92sum(int a, int b)
92{ 93{
93 return a + 94 return a +
94 b; 95 b;
95 return first + 96 return first +
96 second; 97 second;
97} 98}
98//indent end 99//indent end
99 100
100//indent run -ci4 101//indent run -ci4
101int 102int
102sum(int a, int b) 103sum(int a, int b)
103{ 104{
104 return a + 105 return a +
105 b; 106 b;
106 return first + 107 return first +
107 second; 108 second;
108} 109}
109//indent end 110//indent end
110 111
111//indent run -ci8 112//indent run -ci8
112int 113int
113sum(int a, int b) 114sum(int a, int b)
114{ 115{
115 return a + 116 return a +
116 b; 117 b;
117 return first + 118 return first +
118 second; 119 second;
119} 120}
120//indent end 121//indent end
121 122
122 123
123/* 124/*
124 * Continued statements with expressions in parentheses. 125 * Continued statements with expressions in parentheses.
125 */ 126 */
126//indent input 127//indent input
127int 128int
128sum(int a, int b) 129sum(int a, int b)
129{ 130{
130 return (a + 131 return (a +
131 b); 132 b);
132 return (first + 133 return (first +
133 second + ( 134 second + (
134 third)); 135 third));
135} 136}
136//indent end 137//indent end
137 138
138//indent run -ci0 139//indent run -ci0
139int 140int
140sum(int a, int b) 141sum(int a, int b)
141{ 142{
142 return (a + 143 return (a +
143 b); 144 b);
144 return (first + 145 return (first +
145 second + ( 146 second + (
146 third)); 147 third));
147} 148}
148//indent end 149//indent end
149 150
150//indent run-equals-prev-output -ci2 151//indent run-equals-prev-output -ci2
151 152
152//indent run-equals-prev-output -ci4 153//indent run-equals-prev-output -ci4
153 154
154//indent run-equals-prev-output -ci8 155//indent run-equals-prev-output -ci8
155 156
156//indent run -ci2 -nlp 157//indent run -ci2 -nlp
157int 158int
158sum(int a, int b) 159sum(int a, int b)
159{ 160{
160 return (a + 161 return (a +
161 b); 162 b);
162 return (first + 163 return (first +
163 second + ( 164 second + (
164 third)); 165 third));
165} 166}
166//indent end 167//indent end
167 168
168/* 
169 * Since '-ci4' is half an indentation level, indent all continuations using 
170 * the same level, no matter how many parentheses there are. The rationale for 
171 * this may have been to prevent that the continuation line has the same 
172 * indentation as a follow-up statement, such as in 'if' statements. 
173 */ 
174//indent run -ci4 -nlp 169//indent run -ci4 -nlp
175int 170int
176sum(int a, int b) 171sum(int a, int b)
177{ 172{
178 return (a + 173 return (a +
179 b); 174 b);
180 return (first + 175 return (first +
181 second + ( 176 second + (
182 third)); 177 third));
183} 178}
184//indent end 179//indent end
185 180
186//indent run -ci8 -nlp 181//indent run -ci8 -nlp
187int 182int
188sum(int a, int b) 183sum(int a, int b)
189{ 184{
190 return (a + 185 return (a +
191 b); 186 b);
192 return (first + 187 return (first +
193 second + ( 188 second + (
194 third)); 189 third));
195} 190}
196//indent end 191//indent end
197 192
198 193
199/* 194/*
200 * In the default configuration, the indentation level from '-i' is the same 195 * In the default configuration, the indentation level from '-i' is the same
201 * as the continuation indentation from '-ci'. The difference between these 196 * as the continuation indentation from '-ci'. The difference between these
202 * becomes visible for structural macros like 'forever' or 'foreach'. 197 * becomes visible for structural macros like 'forever' or 'foreach'.
203 */ 198 */
204//indent input 199//indent input
205#define forever for (;;) 200#define forever for (;;)
206void 201void
207function(void) 202function(void)
208{ 203{
209 forever 204 forever
210 stmt(); 205 stmt();
211 206
212 forever { 207 forever {
213 stmt(); 208 stmt();
214 } 209 }
215} 210}
216//indent end 211//indent end
217 212
218//indent run-equals-input 213//indent run-equals-input
219 214
220/* 215/*
221 * The difference between the block indentation and the continuation 216 * The difference between the block indentation and the continuation
222 * indentation only becomes visible when these two differ. 217 * indentation only becomes visible when these two differ.
223 */ 218 */
224//indent run -i8 -ci4 219//indent run -i8 -ci4
225#define forever for (;;) 220#define forever for (;;)
226void 221void
227function(void) 222function(void)
228{ 223{
229 forever 224 forever
230 stmt(); 225 stmt();
231 226
232 forever { 227 forever {
233 stmt(); 228 stmt();
234 } 229 }
235} 230}
236//indent end 231//indent end
237 232
238 233
239//indent input 234//indent input
240{ 235{
241 size_t last_word_len = com.len 236 size_t last_word_len = com.len
242 - (size_t)(last_blank + 1); 237 - (size_t)(last_blank + 1);
243} 238}
244//indent end 239//indent end
245 240
246//indent run -ldi0 -ci4 241//indent run -ldi0 -ci4
247{ 242{
248 size_t last_word_len = com.len 243 size_t last_word_len = com.len
249/* $ FIXME: The '-' must be indented by 4 spaces. */ 244/* $ FIXME: The '-' must be indented by 4 spaces. */
250 - (size_t)(last_blank + 1); 245 - (size_t)(last_blank + 1);
251} 246}
252//indent end 247//indent end

cvs diff -r1.9 -r1.10 src/tests/usr.bin/indent/opt_lp.c (switch to unified diff)

--- src/tests/usr.bin/indent/opt_lp.c 2023/06/08 20:36:35 1.9
+++ src/tests/usr.bin/indent/opt_lp.c 2023/06/09 06:36:58 1.10
@@ -1,145 +1,141 @@ @@ -1,145 +1,141 @@
1/* $NetBSD: opt_lp.c,v 1.9 2023/06/08 20:36:35 rillig Exp $ */ 1/* $NetBSD: opt_lp.c,v 1.10 2023/06/09 06:36:58 rillig Exp $ */
2 2
3/* 3/*
4 * Tests for the options '-lp' and '-nlp'. 4 * Tests for the options '-lp' and '-nlp'.
5 * 5 *
6 * The option '-lp' lines up code surrounded by parentheses in continuation 6 * The option '-lp' lines up code surrounded by parentheses in continuation
7 * lines. With '-lp', if a line has a left parenthesis that is not closed on 7 * lines. With '-lp', if a line has a left parenthesis that is not closed on
8 * that line, continuation lines are lined up to start at the character 8 * that line, continuation lines are lined up to start at the character
9 * position just after the left parenthesis. 9 * position just after the left parenthesis.
10 * 10 *
11 * The option '-nlp' indents continuation lines with the continuation 11 * The option '-nlp' indents continuation lines with the continuation
12 * indentation; see '-ci'. 12 * indentation; see '-ci'.
13 */ 13 */
14 14
15//indent input 15//indent input
16void 16void
17example(void) 17example(void)
18{ 18{
19 p1 = first_procedure(second_procedure(p2, p3), 19 p1 = first_procedure(second_procedure(p2, p3),
20 third_procedure(p4, p5)); 20 third_procedure(p4, p5));
21 21
22 p1 = first_procedure(second_procedure(p2, 22 p1 = first_procedure(second_procedure(p2,
23 p3), 23 p3),
24 third_procedure(p4, 24 third_procedure(p4,
25 p5)); 25 p5));
26 26
27 p1 = first_procedure( 27 p1 = first_procedure(
28 second_procedure(p2, p3), 28 second_procedure(p2, p3),
29 third_procedure(p4, p5)); 29 third_procedure(p4, p5));
30} 30}
31//indent end 31//indent end
32 32
33//indent run -lp 33//indent run -lp
34void 34void
35example(void) 35example(void)
36{ 36{
37 p1 = first_procedure(second_procedure(p2, p3), 37 p1 = first_procedure(second_procedure(p2, p3),
38 third_procedure(p4, p5)); 38 third_procedure(p4, p5));
39 39
40 p1 = first_procedure(second_procedure(p2, 40 p1 = first_procedure(second_procedure(p2,
41 p3), 41 p3),
42 third_procedure(p4, 42 third_procedure(p4,
43 p5)); 43 p5));
44 44
45 p1 = first_procedure( 45 p1 = first_procedure(
46 second_procedure(p2, p3), 46 second_procedure(p2, p3),
47 third_procedure(p4, p5)); 47 third_procedure(p4, p5));
48} 48}
49//indent end 49//indent end
50 50
51//indent run -nlp 51//indent run -nlp
52void 52void
53example(void) 53example(void)
54{ 54{
55 p1 = first_procedure(second_procedure(p2, p3), 55 p1 = first_procedure(second_procedure(p2, p3),
56 third_procedure(p4, p5)); 56 third_procedure(p4, p5));
57 57
58 p1 = first_procedure(second_procedure(p2, 58 p1 = first_procedure(second_procedure(p2,
59 p3), 59 p3),
60 third_procedure(p4, 60 third_procedure(p4,
61 p5)); 61 p5));
62 62
63 p1 = first_procedure( 63 p1 = first_procedure(
64 second_procedure(p2, p3), 64 second_procedure(p2, p3),
65 third_procedure(p4, p5)); 65 third_procedure(p4, p5));
66} 66}
67//indent end 67//indent end
68 68
69/* 
70 * XXX: Combining the options '-nlp' and '-ci4' is counterproductive as the 
71 * indentation does not make the nesting level of the function calls visible. 
72 */ 
73//indent run -nlp -ci4 69//indent run -nlp -ci4
74void 70void
75example(void) 71example(void)
76{ 72{
77 p1 = first_procedure(second_procedure(p2, p3), 73 p1 = first_procedure(second_procedure(p2, p3),
78 third_procedure(p4, p5)); 74 third_procedure(p4, p5));
79 75
80 p1 = first_procedure(second_procedure(p2, 76 p1 = first_procedure(second_procedure(p2,
81 p3), 77 p3),
82 third_procedure(p4, 78 third_procedure(p4,
83 p5)); 79 p5));
84 80
85 p1 = first_procedure( 81 p1 = first_procedure(
86 second_procedure(p2, p3), 82 second_procedure(p2, p3),
87 third_procedure(p4, p5)); 83 third_procedure(p4, p5));
88} 84}
89//indent end 85//indent end
90 86
91 87
92/* 88/*
93 * Ensure that in multi-line else-if conditions, all lines are indented by the 89 * Ensure that in multi-line else-if conditions, all lines are indented by the
94 * correct amount. The 'else if' condition is tricky because it has the same 90 * correct amount. The 'else if' condition is tricky because it has the same
95 * indentation as the preceding 'if' condition. 91 * indentation as the preceding 'if' condition.
96 */ 92 */
97//indent input 93//indent input
98{ 94{
99if (cond11a 95if (cond11a
100&& cond11b 96&& cond11b
101&& cond11c) { 97&& cond11c) {
102stmt11; 98stmt11;
103} else if (cond12a 99} else if (cond12a
104&& cond12b 100&& cond12b
105&& cond12c) { 101&& cond12c) {
106stmt12; 102stmt12;
107} 103}
108} 104}
109 105
110{ 106{
111if (cond21a 107if (cond21a
112&& cond21b 108&& cond21b
113&& cond21c) 109&& cond21c)
114stmt21; 110stmt21;
115else if (cond22a 111else if (cond22a
116&& cond22b 112&& cond22b
117&& cond22c) 113&& cond22c)
118stmt22; 114stmt22;
119} 115}
120//indent end 116//indent end
121 117
122//indent run -ci4 -nlp 118//indent run -ci4 -nlp
123{ 119{
124 if (cond11a 120 if (cond11a
125 && cond11b 121 && cond11b
126 && cond11c) { 122 && cond11c) {
127 stmt11; 123 stmt11;
128 } else if (cond12a 124 } else if (cond12a
129 && cond12b 125 && cond12b
130 && cond12c) { 126 && cond12c) {
131 stmt12; 127 stmt12;
132 } 128 }
133} 129}
134 130
135{ 131{
136 if (cond21a 132 if (cond21a
137 && cond21b 133 && cond21b
138 && cond21c) 134 && cond21c)
139 stmt21; 135 stmt21;
140 else if (cond22a 136 else if (cond22a
141 && cond22b 137 && cond22b
142 && cond22c) 138 && cond22c)
143 stmt22; 139 stmt22;
144} 140}
145//indent end 141//indent end

cvs diff -r1.32 -r1.33 src/usr.bin/indent/indent.1 (switch to unified diff)

--- src/usr.bin/indent/indent.1 2023/06/05 10:12:21 1.32
+++ src/usr.bin/indent/indent.1 2023/06/09 06:36:57 1.33
@@ -1,604 +1,603 @@ @@ -1,604 +1,603 @@
1.\" $NetBSD: indent.1,v 1.32 2023/06/05 10:12:21 rillig Exp $ 1.\" $NetBSD: indent.1,v 1.33 2023/06/09 06:36:57 rillig Exp $
2.\" 2.\"
3.\" Copyright (c) 1980, 1990, 1993 3.\" Copyright (c) 1980, 1990, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
5.\" Copyright (c) 1976 Board of Trustees of the University of Illinois. 5.\" Copyright (c) 1976 Board of Trustees of the University of Illinois.
6.\" All rights reserved. 6.\" All rights reserved.
7.\" 7.\"
8.\" Redistribution and use in source and binary forms, with or without 8.\" Redistribution and use in source and binary forms, with or without
9.\" modification, are permitted provided that the following conditions 9.\" modification, are permitted provided that the following conditions
10.\" are met: 10.\" are met:
11.\" 1. Redistributions of source code must retain the above copyright 11.\" 1. Redistributions of source code must retain the above copyright
12.\" notice, this list of conditions and the following disclaimer. 12.\" notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\" notice, this list of conditions and the following disclaimer in the 14.\" notice, this list of conditions and the following disclaimer in the
15.\" documentation and/or other materials provided with the distribution. 15.\" documentation and/or other materials provided with the distribution.
16.\" 3. Neither the name of the University nor the names of its contributors 16.\" 3. Neither the name of the University nor the names of its contributors
17.\" may be used to endorse or promote products derived from this software 17.\" may be used to endorse or promote products derived from this software
18.\" without specific prior written permission. 18.\" without specific prior written permission.
19.\" 19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30.\" SUCH DAMAGE. 30.\" SUCH DAMAGE.
31.\" 31.\"
32.\" @(#)indent.1 8.1 (Berkeley) 7/1/93 32.\" @(#)indent.1 8.1 (Berkeley) 7/1/93
33.\" $FreeBSD: head/usr.bin/indent/indent.1 334944 2018-06-11 05:35:57Z pstef $ 33.\" $FreeBSD: head/usr.bin/indent/indent.1 334944 2018-06-11 05:35:57Z pstef $
34.\" 34.\"
35.Dd June 5, 2023 35.Dd June 9, 2023
36.Dt INDENT 1 36.Dt INDENT 1
37.Os 37.Os
38.Sh NAME 38.Sh NAME
39.Nm indent 39.Nm indent
40.Nd indent and format C program source 40.Nd indent and format C program source
41.Sh SYNOPSIS 41.Sh SYNOPSIS
42.Nm 42.Nm
43.Op Ar input-file Op Ar output-file 43.Op Ar input-file Op Ar output-file
44.Op Fl bacc | Fl nbacc 44.Op Fl bacc | Fl nbacc
45.Op Fl bad | Fl nbad 45.Op Fl bad | Fl nbad
46.Op Fl badp | Fl nbadp 46.Op Fl badp | Fl nbadp
47.Op Fl bap | Fl nbap 47.Op Fl bap | Fl nbap
48.Op Fl bbb | Fl nbbb 48.Op Fl bbb | Fl nbbb
49.Op Fl \&bc | Fl nbc 49.Op Fl \&bc | Fl nbc
50.Op Fl \&bl | Fl \&br 50.Op Fl \&bl | Fl \&br
51.Op Fl bs | Fl nbs 51.Op Fl bs | Fl nbs
52.Op Fl c Ns Ar n 52.Op Fl c Ns Ar n
53.Op Fl \&cd Ns Ar n 53.Op Fl \&cd Ns Ar n
54.Bk -words 54.Bk -words
55.Op Fl cdb | Fl ncdb 55.Op Fl cdb | Fl ncdb
56.Ek 56.Ek
57.Op Fl \&ce | Fl nce 57.Op Fl \&ce | Fl nce
58.Op Fl \&ci Ns Ar n 58.Op Fl \&ci Ns Ar n
59.Op Fl cli Ns Ar n 59.Op Fl cli Ns Ar n
60.Op Fl cs | Fl ncs 60.Op Fl cs | Fl ncs
61.Op Fl d Ns Ar n 61.Op Fl d Ns Ar n
62.Op Fl \&di Ns Ar n 62.Op Fl \&di Ns Ar n
63.Op Fl dj | Fl ndj 63.Op Fl dj | Fl ndj
64.Bk -words 64.Bk -words
65.Op Fl eei | Fl neei 65.Op Fl eei | Fl neei
66.Op Fl ei | Fl nei 66.Op Fl ei | Fl nei
67.Ek 67.Ek
68.Bk -words 68.Bk -words
69.Op Fl fbs | Fl nfbs 69.Op Fl fbs | Fl nfbs
70.Op Fl fc1 | Fl nfc1 70.Op Fl fc1 | Fl nfc1
71.Op Fl fcb | Fl nfcb 71.Op Fl fcb | Fl nfcb
72.Ek 72.Ek
73.Op Fl i Ns Ar n 73.Op Fl i Ns Ar n
74.Op Fl \&ip | Fl nip 74.Op Fl \&ip | Fl nip
75.Op Fl l Ns Ar n 75.Op Fl l Ns Ar n
76.Op Fl \&lc Ns Ar n 76.Op Fl \&lc Ns Ar n
77.Op Fl \&ldi Ns Ar n 77.Op Fl \&ldi Ns Ar n
78.Op Fl \&lp | Fl nlp 78.Op Fl \&lp | Fl nlp
79.Op Fl \&lpl | Fl nlpl 79.Op Fl \&lpl | Fl nlpl
80.Op Fl npro 80.Op Fl npro
81.Op Fl P Ns Ar file 81.Op Fl P Ns Ar file
82.Op Fl pcs | Fl npcs 82.Op Fl pcs | Fl npcs
83.Op Fl psl | Fl npsl 83.Op Fl psl | Fl npsl
84.Op Fl \&sc | Fl nsc 84.Op Fl \&sc | Fl nsc
85.Bk -words 85.Bk -words
86.Op Fl sob | Fl nsob 86.Op Fl sob | Fl nsob
87.Ek 87.Ek
88.Op Fl \&st 88.Op Fl \&st
89.Op Fl \&ta 89.Op Fl \&ta
90.Op Fl T Ns Ar typename 90.Op Fl T Ns Ar typename
91.Op Fl ts Ns Ar n 91.Op Fl ts Ns Ar n
92.Op Fl U Ns Ar file 92.Op Fl U Ns Ar file
93.Op Fl ut | Fl nut 93.Op Fl ut | Fl nut
94.Op Fl v | Fl \&nv 94.Op Fl v | Fl \&nv
95.Op Fl -version 95.Op Fl -version
96.Sh DESCRIPTION 96.Sh DESCRIPTION
97The 97The
98.Nm 98.Nm
99utility is a 99utility is a
100.Em C 100.Em C
101program formatter. 101program formatter.
102It reformats the 102It reformats the
103.Em C 103.Em C
104program in the 104program in the
105.Ar input-file 105.Ar input-file
106according to the switches. 106according to the switches.
107The switches which can be 107The switches which can be
108specified are described below. 108specified are described below.
109They may appear before or after the file 109They may appear before or after the file
110names. 110names.
111.Pp 111.Pp
112.Sy NOTE : 112.Sy NOTE :
113If you only specify an 113If you only specify an
114.Ar input-file , 114.Ar input-file ,
115the formatting is 115the formatting is
116done `in-place', that is, the formatted file is written back into 116done `in-place', that is, the formatted file is written back into
117.Ar input-file 117.Ar input-file
118and a backup copy of 118and a backup copy of
119.Ar input-file 119.Ar input-file
120is written in the current directory. 120is written in the current directory.
121If 121If
122.Ar input-file 122.Ar input-file
123is named 123is named
124.Sq Pa /blah/blah/file , 124.Sq Pa /blah/blah/file ,
125the backup file is named 125the backup file is named
126.Sq Pa file.BAK 126.Sq Pa file.BAK
127by default. 127by default.
128The extension used for the backup file may be overridden using the 128The extension used for the backup file may be overridden using the
129.Ev SIMPLE_BACKUP_SUFFIX 129.Ev SIMPLE_BACKUP_SUFFIX
130environment variable. 130environment variable.
131.Pp 131.Pp
132If 132If
133.Ar output-file 133.Ar output-file
134is specified, 134is specified,
135.Nm 135.Nm
136checks to make sure that it is different from 136checks to make sure that it is different from
137.Ar input-file . 137.Ar input-file .
138.Pp 138.Pp
139The options listed below control the formatting style imposed by 139The options listed below control the formatting style imposed by
140.Nm . 140.Nm .
141.Bl -tag -width Op 141.Bl -tag -width Op
142.It Fl bacc , nbacc 142.It Fl bacc , nbacc
143If 143If
144.Fl bacc 144.Fl bacc
145is specified, a blank line is forced around every conditional 145is specified, a blank line is forced around every conditional
146compilation block. 146compilation block.
147For example, in front of every #ifdef and after every #endif. 147For example, in front of every #ifdef and after every #endif.
148Other blank lines surrounding such blocks will be swallowed. 148Other blank lines surrounding such blocks will be swallowed.
149Default: 149Default:
150.Fl nbacc . 150.Fl nbacc .
151.It Fl bad , nbad 151.It Fl bad , nbad
152If 152If
153.Fl bad 153.Fl bad
154is specified, a blank line is forced after every block of 154is specified, a blank line is forced after every block of
155declarations. 155declarations.
156Default: 156Default:
157.Fl nbad . 157.Fl nbad .
158.It Fl badp , nbadp 158.It Fl badp , nbadp
159This is vaguely similar to 159This is vaguely similar to
160.Fl bad 160.Fl bad
161except that it only applies to the first set of declarations 161except that it only applies to the first set of declarations
162in a procedure (just after the first `{') and it causes a blank 162in a procedure (just after the first `{') and it causes a blank
163line to be generated even if there are no declarations. 163line to be generated even if there are no declarations.
164The default is 164The default is
165.Fl nbadp . 165.Fl nbadp .
166.It Fl bap , nbap 166.It Fl bap , nbap
167If 167If
168.Fl bap 168.Fl bap
169is specified, a blank line is forced after every procedure body. 169is specified, a blank line is forced after every procedure body.
170Default: 170Default:
171.Fl nbap . 171.Fl nbap .
172.It Fl bbb , nbbb 172.It Fl bbb , nbbb
173If 173If
174.Fl bbb 174.Fl bbb
175is specified, a blank line is forced before every block comment. 175is specified, a blank line is forced before every block comment.
176Default: 176Default:
177.Fl nbbb . 177.Fl nbbb .
178.It Fl \&bc , nbc 178.It Fl \&bc , nbc
179If 179If
180.Fl \&bc 180.Fl \&bc
181is specified, then a newline is forced after each comma in a declaration. 181is specified, then a newline is forced after each comma in a declaration.
182.Fl nbc 182.Fl nbc
183turns off this option. 183turns off this option.
184Default: 184Default:
185.Fl \&nbc . 185.Fl \&nbc .
186.It Fl \&bl , \&br 186.It Fl \&bl , \&br
187Specifying 187Specifying
188.Fl \&bl 188.Fl \&bl
189lines up compound statements like this: 189lines up compound statements like this:
190.Bd -literal -offset indent 190.Bd -literal -offset indent
191if (...) 191if (...)
192{ 192{
193 code 193 code
194} 194}
195.Ed 195.Ed
196.Pp 196.Pp
197Specifying 197Specifying
198.Fl \&br 198.Fl \&br
199(the default) makes them look like this: 199(the default) makes them look like this:
200.Bd -literal -offset indent 200.Bd -literal -offset indent
201if (...) { 201if (...) {
202 code 202 code
203} 203}
204.Ed 204.Ed
205.It Fl bs , nbs 205.It Fl bs , nbs
206Whether a blank should always be inserted after sizeof. 206Whether a blank should always be inserted after sizeof.
207The default is 207The default is
208.Fl nbs . 208.Fl nbs .
209.It Fl c Ns Ar n 209.It Fl c Ns Ar n
210The column in which comments on code start. 210The column in which comments on code start.
211The default is 33. 211The default is 33.
212.It Fl cd Ns Ar n 212.It Fl cd Ns Ar n
213The column in which comments on declarations start. 213The column in which comments on declarations start.
214The default 214The default
215is for these comments to start in the same column as those on code. 215is for these comments to start in the same column as those on code.
216.It Fl cdb , ncdb 216.It Fl cdb , ncdb
217Enables (disables) the placement of comment delimiters on blank lines. 217Enables (disables) the placement of comment delimiters on blank lines.
218With 218With
219this option enabled, comments look like this: 219this option enabled, comments look like this:
220.Bd -literal -offset indent 220.Bd -literal -offset indent
221 /* 221 /*
222 * this is a comment 222 * this is a comment
223 */ 223 */
224.Ed 224.Ed
225.Pp 225.Pp
226Rather than like this: 226Rather than like this:
227.Bd -literal -offset indent 227.Bd -literal -offset indent
228 /* this is a comment */ 228 /* this is a comment */
229.Ed 229.Ed
230.Pp 230.Pp
231This only affects block comments, not comments to the right of 231This only affects block comments, not comments to the right of
232code. 232code.
233The default is 233The default is
234.Fl cdb . 234.Fl cdb .
235.It Fl ce , nce 235.It Fl ce , nce
236Enables (disables) forcing of `else's to cuddle up to the immediately preceding 236Enables (disables) forcing of `else's to cuddle up to the immediately preceding
237`}'. 237`}'.
238The default is 238The default is
239.Fl \&ce . 239.Fl \&ce .
240.It Fl \&ci Ns Ar n 240.It Fl \&ci Ns Ar n
241Sets the continuation indent to be 241Sets the continuation indent to be
242.Ar n . 242.Ar n .
243Continuation 243Continuation
244lines will be indented that far from the beginning of the first line of the 244lines will be indented that far from the beginning of the first line of the
245statement. 245statement.
246Parenthesized expressions have extra indentation added to 246Parenthesized expressions have extra indentation added to
247indicate the nesting, unless 247indicate the nesting, unless
248.Fl \&lp 248.Fl \&lp
249is in effect 249is in effect.
250or the continuation indent is exactly half of the main indent. 
251.Fl \&ci 250.Fl \&ci
252defaults to the same value as 251defaults to the same value as
253.Fl i . 252.Fl i .
254.It Fl cli Ns Ar n 253.It Fl cli Ns Ar n
255Causes case labels to be indented 254Causes case labels to be indented
256.Ar n 255.Ar n
257indentation levels to the right of the containing 256indentation levels to the right of the containing
258.Ic switch 257.Ic switch
259statement. 258statement.
260.Fl cli0.5 259.Fl cli0.5
261causes case labels to be indented half an indentation level. 260causes case labels to be indented half an indentation level.
262The 261The
263default is 262default is
264.Fl cli0 . 263.Fl cli0 .
265.It Fl cs , ncs 264.It Fl cs , ncs
266Control whether parenthesized type names in casts are followed by a space or 265Control whether parenthesized type names in casts are followed by a space or
267not. 266not.
268The default is 267The default is
269.Fl ncs . 268.Fl ncs .
270.It Fl d Ns Ar n 269.It Fl d Ns Ar n
271Controls the placement of comments which are not to the 270Controls the placement of comments which are not to the
272right of code. 271right of code.
273For example, 272For example,
274.Fl \&d\&1 273.Fl \&d\&1
275means that such comments are placed one indentation level to the 274means that such comments are placed one indentation level to the
276left of code. 275left of code.
277Specifying the default 276Specifying the default
278.Fl \&d\&0 277.Fl \&d\&0
279lines up these comments with the code. 278lines up these comments with the code.
280See the section on comment 279See the section on comment
281indentation below. 280indentation below.
282.It Fl \&di Ns Ar n 281.It Fl \&di Ns Ar n
283Specifies the indentation, in character positions, 282Specifies the indentation, in character positions,
284of global variable names and all struct/union member names 283of global variable names and all struct/union member names
285relative to the beginning of their type declaration. 284relative to the beginning of their type declaration.
286The default is 285The default is
287.Fl di16 . 286.Fl di16 .
288.It Fl dj , ndj 287.It Fl dj , ndj
289.Fl \&dj 288.Fl \&dj
290left justifies declarations. 289left justifies declarations.
291.Fl ndj 290.Fl ndj
292indents declarations the same as code. 291indents declarations the same as code.
293The default is 292The default is
294.Fl ndj . 293.Fl ndj .
295.It Fl eei , neei 294.It Fl eei , neei
296Enables (disables) extra indentation on continuation lines of 295Enables (disables) extra indentation on continuation lines of
297the expression part of 296the expression part of
298.Ic if 297.Ic if
299and 298and
300.Ic while 299.Ic while
301statements. 300statements.
302These continuation lines will be indented one extra level. 301These continuation lines will be indented one extra level.
303The default is 302The default is
304.Fl neei . 303.Fl neei .
305.It Fl \&ei , nei 304.It Fl \&ei , nei
306Enables (disables) special 305Enables (disables) special
307.Ic else-if 306.Ic else-if
308processing. 307processing.
309If it is enabled, an 308If it is enabled, an
310.Ic if 309.Ic if
311following an 310following an
312.Ic else 311.Ic else
313will have the same indentation as the preceding 312will have the same indentation as the preceding
314.Ic \&if 313.Ic \&if
315statement. 314statement.
316The default is 315The default is
317.Fl ei . 316.Fl ei .
318.It Fl fbs , nfbs 317.It Fl fbs , nfbs
319Enables (disables) splitting the function declaration and opening brace 318Enables (disables) splitting the function declaration and opening brace
320across two lines. 319across two lines.
321The default is 320The default is
322.Fl fbs . 321.Fl fbs .
323.It Fl fc1 , nfc1 322.It Fl fc1 , nfc1
324Enables (disables) the formatting of comments that start in column 1. 323Enables (disables) the formatting of comments that start in column 1.
325Often, comments whose leading `/' is in column 1 have been carefully 324Often, comments whose leading `/' is in column 1 have been carefully
326hand formatted by the programmer. 325hand formatted by the programmer.
327In such cases, 326In such cases,
328.Fl nfc1 327.Fl nfc1
329should be 328should be
330used. 329used.
331The default is 330The default is
332.Fl fc1 . 331.Fl fc1 .
333.It Fl fcb , nfcb 332.It Fl fcb , nfcb
334Enables (disables) the formatting of block comments (ones that begin 333Enables (disables) the formatting of block comments (ones that begin
335with `/*\\n'). 334with `/*\\n').
336Often, block comments have been not so carefully hand formatted by the 335Often, block comments have been not so carefully hand formatted by the
337programmer, but reformatting that would just change the line breaks is not 336programmer, but reformatting that would just change the line breaks is not
338wanted. 337wanted.
339In such cases, 338In such cases,
340.Fl nfcb 339.Fl nfcb
341should be used. 340should be used.
342Block comments are then handled like box comments. 341Block comments are then handled like box comments.
343The default is 342The default is
344.Fl fcb . 343.Fl fcb .
345.It Fl i Ns Ar n 344.It Fl i Ns Ar n
346The number of columns for one indentation level. 345The number of columns for one indentation level.
347The default is 8. 346The default is 8.
348.It Fl \&ip , nip 347.It Fl \&ip , nip
349Enables (disables) the indentation of parameter declarations from the left 348Enables (disables) the indentation of parameter declarations from the left
350margin. 349margin.
351The default is 350The default is
352.Fl \&ip . 351.Fl \&ip .
353.It Fl l Ns Ar n 352.It Fl l Ns Ar n
354Maximum length of an output line. 353Maximum length of an output line.
355The default is 78. 354The default is 78.
356.It Fl lc Ns Ar n 355.It Fl lc Ns Ar n
357Maximum length of an output line in a block comment. 356Maximum length of an output line in a block comment.
358The default is 0, which means to limit block comment lines in accordance with 357The default is 0, which means to limit block comment lines in accordance with
359.Fl l . 358.Fl l .
360.It Fl \&ldi Ns Ar n 359.It Fl \&ldi Ns Ar n
361Specifies the indentation, in character positions, 360Specifies the indentation, in character positions,
362of local variable names 361of local variable names
363relative to the beginning of their type declaration. 362relative to the beginning of their type declaration.
364The default is for local variable names to be indented 363The default is for local variable names to be indented
365by the same amount as global ones. 364by the same amount as global ones.
366.It Fl \&lp , nlp 365.It Fl \&lp , nlp
367Lines up code surrounded by parentheses in continuation lines. 366Lines up code surrounded by parentheses in continuation lines.
368With 367With
369.Fl \&lp , 368.Fl \&lp ,
370if a line 369if a line
371has a left paren which is not closed on that line, then continuation lines 370has a left paren which is not closed on that line, then continuation lines
372will be lined up to start at the character position just after the left 371will be lined up to start at the character position just after the left
373paren. 372paren.
374For example, here is how a piece of continued code looks with 373For example, here is how a piece of continued code looks with
375.Fl nlp 374.Fl nlp
376in effect: 375in effect:
377.Bd -literal -offset indent 376.Bd -literal -offset indent
378p1 = first_procedure(second_procedure(p2, p3), 377p1 = first_procedure(second_procedure(p2, p3),
379\ \ third_procedure(p4, p5)); 378\ \ third_procedure(p4, p5));
380.Ed 379.Ed
381.Pp 380.Pp
382With 381With
383.Fl lp 382.Fl lp
384in effect (the default) the code looks somewhat clearer: 383in effect (the default) the code looks somewhat clearer:
385.Bd -literal -offset indent 384.Bd -literal -offset indent
386p1\ =\ first_procedure(second_procedure(p2,\ p3), 385p1\ =\ first_procedure(second_procedure(p2,\ p3),
387\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ third_procedure(p4,\ p5)); 386\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ third_procedure(p4,\ p5));
388.Ed 387.Ed
389.Pp 388.Pp
390Inserting two more newlines we get: 389Inserting two more newlines we get:
391.Bd -literal -offset indent 390.Bd -literal -offset indent
392p1\ =\ first_procedure(second_procedure(p2, 391p1\ =\ first_procedure(second_procedure(p2,
393\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ p3), 392\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ p3),
394\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ third_procedure(p4, 393\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ third_procedure(p4,
395\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ p5)); 394\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ p5));
396.Ed 395.Ed
397.It Fl \&lpl , nlpl 396.It Fl \&lpl , nlpl
398With 397With
399.Fl \&lpl , 398.Fl \&lpl ,
400code surrounded by parentheses in continuation lines is lined up even if it 399code surrounded by parentheses in continuation lines is lined up even if it
401would extend past the right margin. 400would extend past the right margin.
402With 401With
403.Fl \&nlpl 402.Fl \&nlpl
404(the default), such a line that would extend past the right margin is moved 403(the default), such a line that would extend past the right margin is moved
405left to keep it within the margin, if that does not require placing it to 404left to keep it within the margin, if that does not require placing it to
406the left of the prevailing indentation level. 405the left of the prevailing indentation level.
407These switches have no effect if 406These switches have no effect if
408.Fl nlp 407.Fl nlp
409is selected. 408is selected.
410.It Fl npro 409.It Fl npro
411Causes the profile files, 410Causes the profile files,
412.Sq Pa ./.indent.pro 411.Sq Pa ./.indent.pro
413and 412and
414.Sq Pa ~/.indent.pro , 413.Sq Pa ~/.indent.pro ,
415to be ignored. 414to be ignored.
416.It Fl P Ns Ar file 415.It Fl P Ns Ar file
417Read profile from 416Read profile from
418.Ar file . 417.Ar file .
419.It Fl pcs , npcs 418.It Fl pcs , npcs
420If true 419If true
421.Pq Fl pcs 420.Pq Fl pcs
422all procedure calls will have a space inserted between 421all procedure calls will have a space inserted between
423the name and the `('. 422the name and the `('.
424The default is 423The default is
425.Fl npcs . 424.Fl npcs .
426.It Fl psl , npsl 425.It Fl psl , npsl
427If true 426If true
428.Pq Fl psl 427.Pq Fl psl
429the names of procedures being defined are placed in 428the names of procedures being defined are placed in
430column 1 \- their types, if any, will be left on the previous lines. 429column 1 \- their types, if any, will be left on the previous lines.
431The 430The
432default is 431default is
433.Fl psl . 432.Fl psl .
434.It Fl \&sc , nsc 433.It Fl \&sc , nsc
435Enables (disables) the placement of asterisks (`*'s) at the left edge of all 434Enables (disables) the placement of asterisks (`*'s) at the left edge of all
436comments. 435comments.
437The default is 436The default is
438.Fl sc . 437.Fl sc .
439.It Fl sob , nsob 438.It Fl sob , nsob
440If 439If
441.Fl sob 440.Fl sob
442is specified, indent will swallow optional blank lines. 441is specified, indent will swallow optional blank lines.
443You can use this to 442You can use this to
444get rid of blank lines after declarations. 443get rid of blank lines after declarations.
445Default: 444Default:
446.Fl nsob . 445.Fl nsob .
447.It Fl \&st 446.It Fl \&st
448Causes 447Causes
449.Nm 448.Nm
450to take its input from stdin and put its output to stdout. 449to take its input from stdin and put its output to stdout.
451.It Fl ta 450.It Fl ta
452Automatically add all identifiers ending in "_t" to the list 451Automatically add all identifiers ending in "_t" to the list
453of type keywords. 452of type keywords.
454.It Fl T Ns Ar typename 453.It Fl T Ns Ar typename
455Adds 454Adds
456.Ar typename 455.Ar typename
457to the list of type keywords. 456to the list of type keywords.
458Names accumulate: 457Names accumulate:
459.Fl T 458.Fl T
460can be specified more than once. 459can be specified more than once.
461You need to specify all the typenames that 460You need to specify all the typenames that
462appear in your program that are defined by 461appear in your program that are defined by
463.Ic typedef 462.Ic typedef
464\- nothing will be 463\- nothing will be
465harmed if you miss a few, but the program will not be formatted as nicely as 464harmed if you miss a few, but the program will not be formatted as nicely as
466it should. 465it should.
467This sounds like a painful thing to have to do, but it is really 466This sounds like a painful thing to have to do, but it is really
468a symptom of a problem in C: 467a symptom of a problem in C:
469.Ic typedef 468.Ic typedef
470causes a syntactic change in the 469causes a syntactic change in the
471language and 470language and
472.Nm 471.Nm
473cannot find all 472cannot find all
474instances of 473instances of
475.Ic typedef . 474.Ic typedef .
476.It Fl ts Ns Ar n 475.It Fl ts Ns Ar n
477Assumed distance between tab stops. 476Assumed distance between tab stops.
478The default is 8. 477The default is 8.
479.It Fl U Ns Ar file 478.It Fl U Ns Ar file
480Adds type names from 479Adds type names from
481.Ar file 480.Ar file
482to the list of type keywords. 481to the list of type keywords.
483.It Fl ut , nut 482.It Fl ut , nut
484Enables (disables) the use of tab characters in the output. 483Enables (disables) the use of tab characters in the output.
485The default is 484The default is
486.Fl ut . 485.Fl ut .
487.It Fl v , \&nv 486.It Fl v , \&nv
488.Fl v 487.Fl v
489turns on `verbose' mode; 488turns on `verbose' mode;
490.Fl \&nv 489.Fl \&nv
491turns it off. 490turns it off.
492When in verbose mode, 491When in verbose mode,
493.Nm 492.Nm
494reports its configuration on the standard error output. 493reports its configuration on the standard error output.
495The default is 494The default is
496.Fl \&nv . 495.Fl \&nv .
497.It Fl -version 496.It Fl -version
498Causes 497Causes
499.Nm 498.Nm
500to print its version number and exit. 499to print its version number and exit.
501.El 500.El
502.Pp 501.Pp
503You may set up your own `profile' of defaults to 502You may set up your own `profile' of defaults to
504.Nm 503.Nm
505by creating a file called 504by creating a file called
506.Pa .indent.pro 505.Pa .indent.pro
507in your login directory and/or the current directory and including 506in your login directory and/or the current directory and including
508whatever switches you like. 507whatever switches you like.
509A `.indent.pro' in the current directory takes 508A `.indent.pro' in the current directory takes
510precedence over the one in your login directory. 509precedence over the one in your login directory.
511If 510If
512.Nm 511.Nm
513is run and a profile file exists, then it is read to set up the program's 512is run and a profile file exists, then it is read to set up the program's
514defaults. 513defaults.
515Switches on the command line, though, always override profile 514Switches on the command line, though, always override profile
516switches. 515switches.
517The switches should be separated by spaces, tabs or newlines. 516The switches should be separated by spaces, tabs or newlines.
518.Ss Comments 517.Ss Comments
519.Sq Em Box 518.Sq Em Box
520.Em comments . 519.Em comments .
521The 520The
522.Nm 521.Nm
523utility 522utility
524assumes that any comment with a dash or star immediately after the start of 523assumes that any comment with a dash or star immediately after the start of
525comment (that is, `/*\-' or `/**') is a comment surrounded by a box of stars. 524comment (that is, `/*\-' or `/**') is a comment surrounded by a box of stars.
526Each line of such a comment is left unchanged, except that its indentation 525Each line of such a comment is left unchanged, except that its indentation
527may be adjusted to account for the change in indentation of the first line 526may be adjusted to account for the change in indentation of the first line
528of the comment. 527of the comment.
529.Pp 528.Pp
530.Em Straight text . 529.Em Straight text .
531All other comments are treated as straight text. 530All other comments are treated as straight text.
532The 531The
533.Nm 532.Nm
534utility fits as many words (separated by blanks, tabs, or newlines) on a 533utility fits as many words (separated by blanks, tabs, or newlines) on a
535line as possible. 534line as possible.
536Blank lines break paragraphs. 535Blank lines break paragraphs.
537.Ss Comment indentation 536.Ss Comment indentation
538If a comment is on a line with code it is started in the `comment column', 537If a comment is on a line with code it is started in the `comment column',
539which is set by the 538which is set by the
540.Fl c Ns Ns Ar n 539.Fl c Ns Ns Ar n
541command line parameter. 540command line parameter.
542Otherwise, the comment is started at 541Otherwise, the comment is started at
543.Ar n 542.Ar n
544indentation levels less than where code is currently being placed, where 543indentation levels less than where code is currently being placed, where
545.Ar n 544.Ar n
546is specified by the 545is specified by the
547.Fl d Ns Ns Ar n 546.Fl d Ns Ns Ar n
548command line parameter. 547command line parameter.
549If the code on a line extends past the comment 548If the code on a line extends past the comment
550column, the comment starts further to the right, and the right margin may be 549column, the comment starts further to the right, and the right margin may be
551automatically extended in extreme cases. 550automatically extended in extreme cases.
552.Ss Preprocessor lines 551.Ss Preprocessor lines
553In general, 552In general,
554.Nm 553.Nm
555leaves preprocessor lines alone. 554leaves preprocessor lines alone.
556Conditional compilation 555Conditional compilation
557.Pq Ic #ifdef...#endif 556.Pq Ic #ifdef...#endif
558is recognized and 557is recognized and
559.Nm 558.Nm
560attempts to correctly 559attempts to correctly
561compensate for the syntactic peculiarities introduced. 560compensate for the syntactic peculiarities introduced.
562.Ss C syntax 561.Ss C syntax
563The 562The
564.Nm 563.Nm
565utility understands a substantial amount about the syntax of C, but it 564utility understands a substantial amount about the syntax of C, but it
566has a `forgiving' parser. 565has a `forgiving' parser.
567It attempts to cope with the usual sorts of 566It attempts to cope with the usual sorts of
568incomplete and malformed syntax. 567incomplete and malformed syntax.
569In particular, the use of macros like: 568In particular, the use of macros like:
570.Pp 569.Pp
571.Dl #define forever for(;;) 570.Dl #define forever for(;;)
572.Pp 571.Pp
573is handled properly. 572is handled properly.
574.Sh ENVIRONMENT 573.Sh ENVIRONMENT
575The 574The
576.Nm 575.Nm
577utility uses the 576utility uses the
578.Ev HOME 577.Ev HOME
579environment variable. 578environment variable.
580.Sh FILES 579.Sh FILES
581.Bl -tag -width "./.indent.pro" -compact 580.Bl -tag -width "./.indent.pro" -compact
582.It Pa ./.indent.pro 581.It Pa ./.indent.pro
583profile file 582profile file
584.It Pa ~/.indent.pro 583.It Pa ~/.indent.pro
585profile file 584profile file
586.El 585.El
587.Sh HISTORY 586.Sh HISTORY
588The 587The
589.Nm 588.Nm
590command appeared in 589command appeared in
591.Bx 4.2 . 590.Bx 4.2 .
592.Sh BUGS 591.Sh BUGS
593The 592The
594.Nm 593.Nm
595utility has even more switches than 594utility has even more switches than
596.Xr ls 1 . 595.Xr ls 1 .
597.Pp 596.Pp
598A common mistake is to try to indent all the 597A common mistake is to try to indent all the
599.Em C 598.Em C
600programs in a directory by typing: 599programs in a directory by typing:
601.Pp 600.Pp
602.Dl indent *.c 601.Dl indent *.c
603.Pp 602.Pp
604This is probably a bug, not a feature. 603This is probably a bug, not a feature.

cvs diff -r1.204 -r1.205 src/usr.bin/indent/io.c (switch to unified diff)

--- src/usr.bin/indent/io.c 2023/06/08 20:36:35 1.204
+++ src/usr.bin/indent/io.c 2023/06/09 06:36:57 1.205
@@ -1,394 +1,390 @@ @@ -1,394 +1,390 @@
1/* $NetBSD: io.c,v 1.204 2023/06/08 20:36:35 rillig Exp $ */ 1/* $NetBSD: io.c,v 1.205 2023/06/09 06:36:57 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
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software 19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement: 20 * must display the following acknowledgement:
21 * This product includes software developed by the University of 21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors. 22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors 23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software 24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission. 25 * without specific prior written permission.
26 * 26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
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#include <sys/cdefs.h> 40#include <sys/cdefs.h>
41__RCSID("$NetBSD: io.c,v 1.204 2023/06/08 20:36:35 rillig Exp $"); 41__RCSID("$NetBSD: io.c,v 1.205 2023/06/09 06:36:57 rillig Exp $");
42 42
43#include <stdio.h> 43#include <stdio.h>
44 44
45#include "indent.h" 45#include "indent.h"
46 46
47struct buffer inp; 47struct buffer inp;
48const char *inp_p; 48const char *inp_p;
49 49
50struct output_state out; 50struct output_state out;
51static int out_ind; /* width of the line that is being written */ 51static int out_ind; /* width of the line that is being written */
52static unsigned wrote_newlines = 2; /* 0 in the middle of a line, 1 after a 52static unsigned wrote_newlines = 2; /* 0 in the middle of a line, 1 after a
53 * single '\n', > 1 means there were (n 53 * single '\n', > 1 means there were (n
54 * - 1) blank lines above */ 54 * - 1) blank lines above */
55static int paren_indent; 55static int paren_indent;
56 56
57 57
58static void 58static void
59inp_read_next_line(FILE *f) 59inp_read_next_line(FILE *f)
60{ 60{
61 inp.len = 0; 61 inp.len = 0;
62 62
63 for (;;) { 63 for (;;) {
64 int ch = getc(f); 64 int ch = getc(f);
65 if (ch == EOF) { 65 if (ch == EOF) {
66 if (indent_enabled == indent_on) { 66 if (indent_enabled == indent_on) {
67 buf_add_char(&inp, ' '); 67 buf_add_char(&inp, ' ');
68 buf_add_char(&inp, '\n'); 68 buf_add_char(&inp, '\n');
69 } 69 }
70 had_eof = true; 70 had_eof = true;
71 break; 71 break;
72 } 72 }
73 73
74 if (ch != '\0') 74 if (ch != '\0')
75 buf_add_char(&inp, (char)ch); 75 buf_add_char(&inp, (char)ch);
76 if (ch == '\n') 76 if (ch == '\n')
77 break; 77 break;
78 } 78 }
79 inp_p = inp.s; 79 inp_p = inp.s;
80} 80}
81 81
82void 82void
83inp_read_line(void) 83inp_read_line(void)
84{ 84{
85 if (indent_enabled == indent_on) 85 if (indent_enabled == indent_on)
86 out.indent_off_text.len = 0; 86 out.indent_off_text.len = 0;
87 buf_add_chars(&out.indent_off_text, inp.s, inp.len); 87 buf_add_chars(&out.indent_off_text, inp.s, inp.len);
88 inp_read_next_line(input); 88 inp_read_next_line(input);
89} 89}
90 90
91void 91void
92inp_skip(void) 92inp_skip(void)
93{ 93{
94 inp_p++; 94 inp_p++;
95 if ((size_t)(inp_p - inp.s) >= inp.len) 95 if ((size_t)(inp_p - inp.s) >= inp.len)
96 inp_read_line(); 96 inp_read_line();
97} 97}
98 98
99char 99char
100inp_next(void) 100inp_next(void)
101{ 101{
102 char ch = inp_p[0]; 102 char ch = inp_p[0];
103 inp_skip(); 103 inp_skip();
104 return ch; 104 return ch;
105} 105}
106 106
107 107
108static void 108static void
109output_newline(void) 109output_newline(void)
110{ 110{
111 fputc('\n', output); 111 fputc('\n', output);
112 debug_println("output_newline"); 112 debug_println("output_newline");
113 wrote_newlines++; 113 wrote_newlines++;
114 out_ind = 0; 114 out_ind = 0;
115} 115}
116 116
117static void 117static void
118output_range(const char *s, size_t len) 118output_range(const char *s, size_t len)
119{ 119{
120 fwrite(s, 1, len, output); 120 fwrite(s, 1, len, output);
121 debug_vis_range("output_range \"", s, len, "\"\n"); 121 debug_vis_range("output_range \"", s, len, "\"\n");
122 for (size_t i = 0; i < len; i++) 122 for (size_t i = 0; i < len; i++)
123 wrote_newlines = s[i] == '\n' ? wrote_newlines + 1 : 0; 123 wrote_newlines = s[i] == '\n' ? wrote_newlines + 1 : 0;
124 out_ind = ind_add(out_ind, s, len); 124 out_ind = ind_add(out_ind, s, len);
125} 125}
126 126
127static void 127static void
128output_indent(int new_ind) 128output_indent(int new_ind)
129{ 129{
130 int ind = out_ind; 130 int ind = out_ind;
131 131
132 if (opt.use_tabs) { 132 if (opt.use_tabs) {
133 int n = new_ind / opt.tabsize - ind / opt.tabsize; 133 int n = new_ind / opt.tabsize - ind / opt.tabsize;
134 if (n > 0) { 134 if (n > 0) {
135 ind = ind - ind % opt.tabsize + n * opt.tabsize; 135 ind = ind - ind % opt.tabsize + n * opt.tabsize;
136 while (n-- > 0) 136 while (n-- > 0)
137 fputc('\t', output); 137 fputc('\t', output);
138 wrote_newlines = 0; 138 wrote_newlines = 0;
139 } 139 }
140 } 140 }
141 141
142 for (; ind < new_ind; ind++) { 142 for (; ind < new_ind; ind++) {
143 fputc(' ', output); 143 fputc(' ', output);
144 wrote_newlines = 0; 144 wrote_newlines = 0;
145 } 145 }
146 146
147 debug_println("output_indent %d", ind); 147 debug_println("output_indent %d", ind);
148 out_ind = ind; 148 out_ind = ind;
149} 149}
150 150
151static bool 151static bool
152want_blank_line(void) 152want_blank_line(void)
153{ 153{
154 debug_println("%s: %s -> %s", __func__, 154 debug_println("%s: %s -> %s", __func__,
155 line_kind_name[out.prev_line_kind], line_kind_name[out.line_kind]); 155 line_kind_name[out.prev_line_kind], line_kind_name[out.line_kind]);
156 156
157 if (ps.blank_line_after_decl && ps.declaration == decl_no) { 157 if (ps.blank_line_after_decl && ps.declaration == decl_no) {
158 ps.blank_line_after_decl = false; 158 ps.blank_line_after_decl = false;
159 return true; 159 return true;
160 } 160 }
161 if (opt.blanklines_around_conditional_compilation) { 161 if (opt.blanklines_around_conditional_compilation) {
162 if (out.prev_line_kind != lk_if && out.line_kind == lk_if) 162 if (out.prev_line_kind != lk_if && out.line_kind == lk_if)
163 return true; 163 return true;
164 if (out.prev_line_kind == lk_endif 164 if (out.prev_line_kind == lk_endif
165 && out.line_kind != lk_endif) 165 && out.line_kind != lk_endif)
166 return true; 166 return true;
167 } 167 }
168 if (opt.blanklines_after_procs && out.prev_line_kind == lk_func_end 168 if (opt.blanklines_after_procs && out.prev_line_kind == lk_func_end
169 && out.line_kind != lk_endif) 169 && out.line_kind != lk_endif)
170 return true; 170 return true;
171 if (opt.blanklines_before_block_comments 171 if (opt.blanklines_before_block_comments
172 && out.line_kind == lk_block_comment) 172 && out.line_kind == lk_block_comment)
173 return true; 173 return true;
174 return false; 174 return false;
175} 175}
176 176
177static bool 177static bool
178is_blank_line_optional(void) 178is_blank_line_optional(void)
179{ 179{
180 if (out.prev_line_kind == lk_stmt_head) 180 if (out.prev_line_kind == lk_stmt_head)
181 return wrote_newlines >= 1; 181 return wrote_newlines >= 1;
182 if (ps.psyms.top >= 2) 182 if (ps.psyms.top >= 2)
183 return wrote_newlines >= 2; 183 return wrote_newlines >= 2;
184 return wrote_newlines >= 3; 184 return wrote_newlines >= 3;
185} 185}
186 186
187static int 187static int
188compute_case_label_indent(void) 188compute_case_label_indent(void)
189{ 189{
190 int i = ps.psyms.top; 190 int i = ps.psyms.top;
191 while (i > 0 && ps.psyms.sym[i] != psym_switch_expr) 191 while (i > 0 && ps.psyms.sym[i] != psym_switch_expr)
192 i--; 192 i--;
193 float case_ind = (float)ps.psyms.ind_level[i] + opt.case_indent; 193 float case_ind = (float)ps.psyms.ind_level[i] + opt.case_indent;
194 return (int)(case_ind * (float)opt.indent_size); 194 return (int)(case_ind * (float)opt.indent_size);
195} 195}
196 196
197int 197int
198compute_label_indent(void) 198compute_label_indent(void)
199{ 199{
200 if (out.line_kind == lk_case_or_default) 200 if (out.line_kind == lk_case_or_default)
201 return compute_case_label_indent(); 201 return compute_case_label_indent();
202 if (lab.s[0] == '#') 202 if (lab.s[0] == '#')
203 return 0; 203 return 0;
204 return opt.indent_size * (ps.ind_level - 2); 204 return opt.indent_size * (ps.ind_level - 2);
205} 205}
206 206
207static void 207static void
208output_line_label(void) 208output_line_label(void)
209{ 209{
210 output_indent(compute_label_indent()); 210 output_indent(compute_label_indent());
211 output_range(lab.s, lab.len); 211 output_range(lab.s, lab.len);
212} 212}
213 213
214static int 214static int
215compute_code_indent_lineup(int base_ind) 215compute_code_indent_lineup(int base_ind)
216{ 216{
217 int ind = paren_indent; 217 int ind = paren_indent;
218 int overflow = ind_add(ind, code.s, code.len) - opt.max_line_length; 218 int overflow = ind_add(ind, code.s, code.len) - opt.max_line_length;
219 if (overflow < 0) 219 if (overflow < 0)
220 return ind; 220 return ind;
221 221
222 if (ind_add(base_ind, code.s, code.len) < opt.max_line_length) { 222 if (ind_add(base_ind, code.s, code.len) < opt.max_line_length) {
223 ind -= overflow + 2; 223 ind -= overflow + 2;
224 if (ind > base_ind) 224 if (ind > base_ind)
225 return ind; 225 return ind;
226 return base_ind; 226 return base_ind;
227 } 227 }
228 228
229 return ind; 229 return ind;
230} 230}
231 231
232int 232int
233compute_code_indent(void) 233compute_code_indent(void)
234{ 234{
235 int base_ind = ps.ind_level * opt.indent_size; 235 int base_ind = ps.ind_level * opt.indent_size;
236 236
237 if (ps.line_start_nparen == 0) { 237 if (ps.line_start_nparen == 0) {
238 if (ps.psyms.top >= 1 238 if (ps.psyms.top >= 1
239 && ps.psyms.sym[ps.psyms.top - 1] == psym_lbrace_enum) 239 && ps.psyms.sym[ps.psyms.top - 1] == psym_lbrace_enum)
240 return base_ind; 240 return base_ind;
241 if (ps.in_stmt_cont) 241 if (ps.in_stmt_cont)
242 return base_ind + opt.continuation_indent; 242 return base_ind + opt.continuation_indent;
243 return base_ind; 243 return base_ind;
244 } 244 }
245 245
246 if (opt.lineup_to_parens) { 246 if (opt.lineup_to_parens) {
247 if (opt.lineup_to_parens_always) 247 if (opt.lineup_to_parens_always)
248 return paren_indent; 248 return paren_indent;
249 return compute_code_indent_lineup(base_ind); 249 return compute_code_indent_lineup(base_ind);
250 } 250 }
251 251
252 if (ps.extra_expr_indent != eei_no) 252 if (ps.extra_expr_indent != eei_no)
253 return base_ind + 2 * opt.continuation_indent; 253 return base_ind + 2 * opt.continuation_indent;
254 254
255 if (2 * opt.continuation_indent == opt.indent_size) 255 return base_ind + opt.continuation_indent * ps.line_start_nparen;
256 return base_ind + opt.continuation_indent; 
257 else 
258 return base_ind + 
259 opt.continuation_indent * ps.line_start_nparen; 
260} 256}
261 257
262static void 258static void
263output_line_code(void) 259output_line_code(void)
264{ 260{
265 int target_ind = compute_code_indent(); 261 int target_ind = compute_code_indent();
266 for (int i = 0; i < ps.nparen; i++) { 262 for (int i = 0; i < ps.nparen; i++) {
267 int paren_ind = ps.paren[i].indent; 263 int paren_ind = ps.paren[i].indent;
268 if (paren_ind >= 0) { 264 if (paren_ind >= 0) {
269 ps.paren[i].indent = -1 - (paren_ind + target_ind); 265 ps.paren[i].indent = -1 - (paren_ind + target_ind);
270 debug_println( 266 debug_println(
271 "setting paren_indents[%d] from %d to %d " 267 "setting paren_indents[%d] from %d to %d "
272 "for column %d", 268 "for column %d",
273 i, paren_ind, ps.paren[i].indent, target_ind + 1); 269 i, paren_ind, ps.paren[i].indent, target_ind + 1);
274 } 270 }
275 } 271 }
276 272
277 if (lab.len > 0 && target_ind <= out_ind) 273 if (lab.len > 0 && target_ind <= out_ind)
278 output_range(" ", 1); 274 output_range(" ", 1);
279 output_indent(target_ind); 275 output_indent(target_ind);
280 output_range(code.s, code.len); 276 output_range(code.s, code.len);
281} 277}
282 278
283static void 279static void
284output_line_comment(void) 280output_line_comment(void)
285{ 281{
286 int target_ind = ps.com_ind + ps.comment_delta; 282 int target_ind = ps.com_ind + ps.comment_delta;
287 const char *p; 283 const char *p;
288 284
289 /* consider original indentation in case this is a box comment */ 285 /* consider original indentation in case this is a box comment */
290 for (p = com.s; *p == '\t'; p++) 286 for (p = com.s; *p == '\t'; p++)
291 target_ind += opt.tabsize; 287 target_ind += opt.tabsize;
292 288
293 for (; target_ind < 0; p++) { 289 for (; target_ind < 0; p++) {
294 if (*p == ' ') 290 if (*p == ' ')
295 target_ind++; 291 target_ind++;
296 else if (*p == '\t') 292 else if (*p == '\t')
297 target_ind = next_tab(target_ind); 293 target_ind = next_tab(target_ind);
298 else { 294 else {
299 target_ind = 0; 295 target_ind = 0;
300 break; 296 break;
301 } 297 }
302 } 298 }
303 299
304 if (out_ind > target_ind) 300 if (out_ind > target_ind)
305 output_newline(); 301 output_newline();
306 302
307 while (com.s + com.len > p && ch_isspace(com.s[com.len - 1])) 303 while (com.s + com.len > p && ch_isspace(com.s[com.len - 1]))
308 com.len--; 304 com.len--;
309 305
310 output_indent(target_ind); 306 output_indent(target_ind);
311 output_range(p, com.len - (size_t)(p - com.s)); 307 output_range(p, com.len - (size_t)(p - com.s));
312 308
313 ps.comment_delta = ps.n_comment_delta; 309 ps.comment_delta = ps.n_comment_delta;
314} 310}
315 311
316/* 312/*
317 * Write a line of formatted source to the output file. The line consists of 313 * Write a line of formatted source to the output file. The line consists of
318 * the label, the code and the comment. 314 * the label, the code and the comment.
319 */ 315 */
320void 316void
321output_line(void) 317output_line(void)
322{ 318{
323 debug_blank_line(); 319 debug_blank_line();
324 debug_printf("%s", __func__); 320 debug_printf("%s", __func__);
325 debug_buffers(); 321 debug_buffers();
326 322
327 ps.is_function_definition = false; 323 ps.is_function_definition = false;
328 324
329 if (indent_enabled == indent_on) { 325 if (indent_enabled == indent_on) {
330 if (lab.len == 0 && code.len == 0 && com.len == 0) 326 if (lab.len == 0 && code.len == 0 && com.len == 0)
331 out.line_kind = lk_blank; 327 out.line_kind = lk_blank;
332 328
333 if (want_blank_line() && wrote_newlines < 2 329 if (want_blank_line() && wrote_newlines < 2
334 && out.line_kind != lk_blank) 330 && out.line_kind != lk_blank)
335 output_newline(); 331 output_newline();
336 332
337 /* This kludge aligns function definitions correctly. */ 333 /* This kludge aligns function definitions correctly. */
338 if (ps.ind_level == 0) 334 if (ps.ind_level == 0)
339 ps.in_stmt_cont = false; 335 ps.in_stmt_cont = false;
340 336
341 if (opt.blank_line_after_decl && ps.declaration == decl_end 337 if (opt.blank_line_after_decl && ps.declaration == decl_end
342 && ps.psyms.top > 1) { 338 && ps.psyms.top > 1) {
343 ps.declaration = decl_no; 339 ps.declaration = decl_no;
344 ps.blank_line_after_decl = true; 340 ps.blank_line_after_decl = true;
345 } 341 }
346 342
347 if (opt.swallow_optional_blanklines 343 if (opt.swallow_optional_blanklines
348 && out.line_kind == lk_blank 344 && out.line_kind == lk_blank
349 && is_blank_line_optional()) 345 && is_blank_line_optional())
350 goto prepare_next_line; 346 goto prepare_next_line;
351 347
352 if (lab.len > 0) 348 if (lab.len > 0)
353 output_line_label(); 349 output_line_label();
354 if (code.len > 0) 350 if (code.len > 0)
355 output_line_code(); 351 output_line_code();
356 if (com.len > 0) 352 if (com.len > 0)
357 output_line_comment(); 353 output_line_comment();
358 354
359 output_newline(); 355 output_newline();
360 out.prev_line_kind = out.line_kind; 356 out.prev_line_kind = out.line_kind;
361 } 357 }
362 358
363 if (indent_enabled == indent_last_off_line) { 359 if (indent_enabled == indent_last_off_line) {
364 indent_enabled = indent_on; 360 indent_enabled = indent_on;
365 output_range(out.indent_off_text.s, out.indent_off_text.len); 361 output_range(out.indent_off_text.s, out.indent_off_text.len);
366 out.indent_off_text.len = 0; 362 out.indent_off_text.len = 0;
367 } 363 }
368 364
369prepare_next_line: 365prepare_next_line:
370 lab.len = 0; 366 lab.len = 0;
371 code.len = 0; 367 code.len = 0;
372 com.len = 0; 368 com.len = 0;
373 369
374 ps.decl_on_line = ps.in_decl; 370 ps.decl_on_line = ps.in_decl;
375 // XXX: don't reset in_stmt_cont here; see process_colon_question. 371 // XXX: don't reset in_stmt_cont here; see process_colon_question.
376 ps.in_stmt_cont = ps.in_stmt_or_decl 372 ps.in_stmt_cont = ps.in_stmt_or_decl
377 && !ps.in_decl && ps.block_init_level == 0; 373 && !ps.in_decl && ps.block_init_level == 0;
378 ps.decl_indent_done = false; 374 ps.decl_indent_done = false;
379 if (ps.extra_expr_indent == eei_last) 375 if (ps.extra_expr_indent == eei_last)
380 ps.extra_expr_indent = eei_no; 376 ps.extra_expr_indent = eei_no;
381 if (!(ps.psyms.sym[ps.psyms.top] == psym_if_expr_stmt_else 377 if (!(ps.psyms.sym[ps.psyms.top] == psym_if_expr_stmt_else
382 && ps.nparen > 0)) 378 && ps.nparen > 0))
383 ps.ind_level = ps.ind_level_follow; 379 ps.ind_level = ps.ind_level_follow;
384 ps.line_start_nparen = ps.nparen; 380 ps.line_start_nparen = ps.nparen;
385 ps.want_blank = false; 381 ps.want_blank = false;
386 382
387 if (ps.nparen > 0) { 383 if (ps.nparen > 0) {
388 /* TODO: explain what negative indentation means */ 384 /* TODO: explain what negative indentation means */
389 paren_indent = -1 - ps.paren[ps.nparen - 1].indent; 385 paren_indent = -1 - ps.paren[ps.nparen - 1].indent;
390 debug_println("paren_indent is now %d", paren_indent); 386 debug_println("paren_indent is now %d", paren_indent);
391 } 387 }
392 388
393 out.line_kind = lk_other; 389 out.line_kind = lk_other;
394} 390}