xref: /netbsd-src/usr.bin/indent/debug.c (revision 8af25fb9d1850e3f176f367bb813de1e1e8a3a82)
1*8af25fb9Srillig /*	$NetBSD: debug.c,v 1.74 2025/01/04 21:20:59 rillig Exp $	*/
2ff5c4a3fSrillig 
3ff5c4a3fSrillig /*-
4ff5c4a3fSrillig  * Copyright (c) 2023 The NetBSD Foundation, Inc.
5ff5c4a3fSrillig  * All rights reserved.
6ff5c4a3fSrillig  *
7ff5c4a3fSrillig  * This code is derived from software contributed to The NetBSD Foundation
8ff5c4a3fSrillig  * by Roland Illig <rillig@NetBSD.org>.
9ff5c4a3fSrillig  *
10ff5c4a3fSrillig  * Redistribution and use in source and binary forms, with or without
11ff5c4a3fSrillig  * modification, are permitted provided that the following conditions
12ff5c4a3fSrillig  * are met:
13ff5c4a3fSrillig  * 1. Redistributions of source code must retain the above copyright
14ff5c4a3fSrillig  *    notice, this list of conditions and the following disclaimer.
15ff5c4a3fSrillig  * 2. Redistributions in binary form must reproduce the above copyright
16ff5c4a3fSrillig  *    notice, this list of conditions and the following disclaimer in the
17ff5c4a3fSrillig  *    documentation and/or other materials provided with the distribution.
18ff5c4a3fSrillig  *
19ff5c4a3fSrillig  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20ff5c4a3fSrillig  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21ff5c4a3fSrillig  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22ff5c4a3fSrillig  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23ff5c4a3fSrillig  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24ff5c4a3fSrillig  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25ff5c4a3fSrillig  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26ff5c4a3fSrillig  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27ff5c4a3fSrillig  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28ff5c4a3fSrillig  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29ff5c4a3fSrillig  * POSSIBILITY OF SUCH DAMAGE.
30ff5c4a3fSrillig  */
31ff5c4a3fSrillig 
32ff5c4a3fSrillig #include <sys/cdefs.h>
33*8af25fb9Srillig __RCSID("$NetBSD: debug.c,v 1.74 2025/01/04 21:20:59 rillig Exp $");
3444b10107Srillig 
3544b10107Srillig #include <stdarg.h>
3689f19ae3Srillig #include <string.h>
37ff5c4a3fSrillig 
38ff5c4a3fSrillig #include "indent.h"
39ff5c4a3fSrillig 
40ff5c4a3fSrillig #ifdef debug
41d78c6debSrillig 
4289f19ae3Srillig static struct {
43b520fe89Srillig 	// false	show only the changes to the parser state
44b520fe89Srillig 	// true		show unchanged parts of the parser state as well
4589f19ae3Srillig 	bool full_parser_state;
4689f19ae3Srillig } config = {
4789f19ae3Srillig 	.full_parser_state = false,
4889f19ae3Srillig };
49d78c6debSrillig 
50ff5c4a3fSrillig const char *const lsym_name[] = {
51d40c8c6bSrillig 	"lsym_eof",
52d40c8c6bSrillig 	"lsym_preprocessing",
53d40c8c6bSrillig 	"lsym_newline",
54d40c8c6bSrillig 	"lsym_comment",
55d40c8c6bSrillig 	"lsym_lparen",
56d40c8c6bSrillig 	"lsym_rparen",
57d40c8c6bSrillig 	"lsym_lbracket",
58d40c8c6bSrillig 	"lsym_rbracket",
59d40c8c6bSrillig 	"lsym_lbrace",
60d40c8c6bSrillig 	"lsym_rbrace",
61d40c8c6bSrillig 	"lsym_period",
62d40c8c6bSrillig 	"lsym_unary_op",
63d40c8c6bSrillig 	"lsym_sizeof",
64d40c8c6bSrillig 	"lsym_offsetof",
65d40c8c6bSrillig 	"lsym_postfix_op",
66d40c8c6bSrillig 	"lsym_binary_op",
67d40c8c6bSrillig 	"lsym_question",
68d40c8c6bSrillig 	"lsym_question_colon",
69d40c8c6bSrillig 	"lsym_comma",
70d40c8c6bSrillig 	"lsym_typedef",
71d40c8c6bSrillig 	"lsym_modifier",
72d40c8c6bSrillig 	"lsym_tag",
73d40c8c6bSrillig 	"lsym_type",
74d40c8c6bSrillig 	"lsym_word",
75d40c8c6bSrillig 	"lsym_funcname",
76d40c8c6bSrillig 	"lsym_label_colon",
77d40c8c6bSrillig 	"lsym_other_colon",
78d40c8c6bSrillig 	"lsym_semicolon",
79d40c8c6bSrillig 	"lsym_case",
80d40c8c6bSrillig 	"lsym_default",
81d40c8c6bSrillig 	"lsym_do",
82d40c8c6bSrillig 	"lsym_else",
83d40c8c6bSrillig 	"lsym_for",
84d40c8c6bSrillig 	"lsym_if",
85d40c8c6bSrillig 	"lsym_switch",
86d40c8c6bSrillig 	"lsym_while",
87d40c8c6bSrillig 	"lsym_return",
88ff5c4a3fSrillig };
89ff5c4a3fSrillig 
90ff5c4a3fSrillig const char *const psym_name[] = {
91d40c8c6bSrillig 	"psym_0",
92d40c8c6bSrillig 	"psym_lbrace_block",
93d40c8c6bSrillig 	"psym_lbrace_struct",
94d40c8c6bSrillig 	"psym_lbrace_union",
95d40c8c6bSrillig 	"psym_lbrace_enum",
96d40c8c6bSrillig 	"psym_rbrace",
97d40c8c6bSrillig 	"psym_decl",
98d40c8c6bSrillig 	"psym_stmt",
99d40c8c6bSrillig 	"psym_for_exprs",
100d40c8c6bSrillig 	"psym_if_expr",
101d40c8c6bSrillig 	"psym_if_expr_stmt",
102d40c8c6bSrillig 	"psym_if_expr_stmt_else",
103d40c8c6bSrillig 	"psym_else",
104d40c8c6bSrillig 	"psym_switch_expr",
105d40c8c6bSrillig 	"psym_do",
106d40c8c6bSrillig 	"psym_do_stmt",
107d40c8c6bSrillig 	"psym_while_expr",
108ff5c4a3fSrillig };
109ff5c4a3fSrillig 
110e914aa7bSrillig static const char *const newline_name[] = {
111d40c8c6bSrillig 	"nl_no",
112d40c8c6bSrillig 	"nl_unless_if",
113d40c8c6bSrillig 	"nl_unless_lbrace",
114d40c8c6bSrillig 	"nl_unless_semicolon",
115d40c8c6bSrillig 	"nl_yes",
116e914aa7bSrillig };
117e914aa7bSrillig 
118a0b2b7f9Srillig static const char *const declaration_name[] = {
119d40c8c6bSrillig 	"decl_no",
120d40c8c6bSrillig 	"decl_begin",
121d40c8c6bSrillig 	"decl_end",
122ae0013d2Srillig };
123ae0013d2Srillig 
124f73b959dSrillig static const char *const badp_name[] = {
125d40c8c6bSrillig 	"badp_none",
126d40c8c6bSrillig 	"badp_seen_lbrace",
127d40c8c6bSrillig 	"badp_decl",
128d40c8c6bSrillig 	"badp_seen_decl",
129d40c8c6bSrillig 	"badp_yes",
130f73b959dSrillig };
131f73b959dSrillig 
132a0b2b7f9Srillig const char *const paren_level_cast_name[] = {
133d40c8c6bSrillig 	"cast_unknown",
134d40c8c6bSrillig 	"cast_maybe",
135d40c8c6bSrillig 	"cast_no",
136a0b2b7f9Srillig };
137a0b2b7f9Srillig 
1384fb425a2Srillig const char *const line_kind_name[] = {
139d40c8c6bSrillig 	"lk_other",
140d40c8c6bSrillig 	"lk_blank",
141d40c8c6bSrillig 	"lk_pre_if",
142d40c8c6bSrillig 	"lk_pre_endif",
143d40c8c6bSrillig 	"lk_pre_other",
144d40c8c6bSrillig 	"lk_stmt_head",
145d40c8c6bSrillig 	"lk_func_end",
146d40c8c6bSrillig 	"lk_block_comment",
147d40c8c6bSrillig 	"lk_case_or_default",
1484d19140dSrillig };
1494d19140dSrillig 
1502a46ceffSrillig static const char *const extra_expr_indent_name[] = {
151d40c8c6bSrillig 	"eei_no",
152d40c8c6bSrillig 	"eei_maybe",
153d40c8c6bSrillig 	"eei_last"
1542a46ceffSrillig };
1552a46ceffSrillig 
15689f19ae3Srillig static struct {
15789f19ae3Srillig 	struct parser_state prev_ps;
15889f19ae3Srillig 	bool ps_first;
159d40c8c6bSrillig 	const char *heading1;
160d40c8c6bSrillig 	const char *heading2;
16189f19ae3Srillig 	unsigned wrote_newlines;
16289f19ae3Srillig } state = {
16389f19ae3Srillig 	.ps_first = true,
16489f19ae3Srillig 	.wrote_newlines = 1,
16589f19ae3Srillig };
1665f6e61d7Srillig 
167d40c8c6bSrillig static FILE *
168d40c8c6bSrillig debug_file(void)
169d40c8c6bSrillig {
170d40c8c6bSrillig 	return output == stdout ? stderr : stdout;
171d40c8c6bSrillig }
172d40c8c6bSrillig 
173d40c8c6bSrillig static void
174d40c8c6bSrillig debug_print_headings(void)
175d40c8c6bSrillig {
176d40c8c6bSrillig 	if (state.heading1 != NULL) {
177d40c8c6bSrillig 		(void)fprintf(debug_file(), "%s:\n", state.heading1);
178d40c8c6bSrillig 		state.heading1 = NULL;
179d40c8c6bSrillig 		state.wrote_newlines = 1;
180d40c8c6bSrillig 	}
181d40c8c6bSrillig 	if (state.heading2 != NULL) {
182d40c8c6bSrillig 		(void)fprintf(debug_file(), "\t%s:\n", state.heading2);
183d40c8c6bSrillig 		state.heading2 = NULL;
184d40c8c6bSrillig 		state.wrote_newlines = 1;
185d40c8c6bSrillig 	}
186d40c8c6bSrillig }
187d40c8c6bSrillig 
18844b10107Srillig void
18944b10107Srillig debug_printf(const char *fmt, ...)
19044b10107Srillig {
19144b10107Srillig 	va_list ap;
19244b10107Srillig 
193d40c8c6bSrillig 	debug_print_headings();
19444b10107Srillig 	va_start(ap, fmt);
195d40c8c6bSrillig 	(void)vfprintf(debug_file(), fmt, ap);
19644b10107Srillig 	va_end(ap);
19789f19ae3Srillig 	state.wrote_newlines = 0;
19844b10107Srillig }
19944b10107Srillig 
20044b10107Srillig void
20144b10107Srillig debug_println(const char *fmt, ...)
20244b10107Srillig {
20344b10107Srillig 	va_list ap;
20444b10107Srillig 
205d40c8c6bSrillig 	debug_print_headings();
20644b10107Srillig 	va_start(ap, fmt);
207d40c8c6bSrillig 	(void)vfprintf(debug_file(), fmt, ap);
20844b10107Srillig 	va_end(ap);
209d40c8c6bSrillig 	(void)fprintf(debug_file(), "\n");
21089f19ae3Srillig 	state.wrote_newlines = fmt[0] == '\0' ? state.wrote_newlines + 1 : 1;
211fe5b389bSrillig }
212fe5b389bSrillig 
213fe5b389bSrillig void
214fe5b389bSrillig debug_blank_line(void)
215fe5b389bSrillig {
21689f19ae3Srillig 	while (state.wrote_newlines < 2)
217fe5b389bSrillig 		debug_println("");
21844b10107Srillig }
21944b10107Srillig 
22044b10107Srillig void
221b520fe89Srillig debug_vis_range(const char *s, size_t len)
22244b10107Srillig {
223b520fe89Srillig 	debug_printf("\"");
22444b10107Srillig 	for (size_t i = 0; i < len; i++) {
22544b10107Srillig 		const char *p = s + i;
22644b10107Srillig 		if (*p == '\\' || *p == '"')
22744b10107Srillig 			debug_printf("\\%c", *p);
22844b10107Srillig 		else if (isprint((unsigned char)*p))
22944b10107Srillig 			debug_printf("%c", *p);
23044b10107Srillig 		else if (*p == '\n')
23144b10107Srillig 			debug_printf("\\n");
23244b10107Srillig 		else if (*p == '\t')
23344b10107Srillig 			debug_printf("\\t");
23444b10107Srillig 		else
23544b10107Srillig 			debug_printf("\\x%02x", (unsigned char)*p);
23644b10107Srillig 	}
237b520fe89Srillig 	debug_printf("\"");
23844b10107Srillig }
23944b10107Srillig 
240ef25c88eSrillig void
241ff5c4a3fSrillig debug_print_buf(const char *name, const struct buffer *buf)
242ff5c4a3fSrillig {
2439a2185a1Srillig 	if (buf->len > 0) {
244ff5c4a3fSrillig 		debug_printf(" %s ", name);
245b520fe89Srillig 		debug_vis_range(buf->s, buf->len);
246ff5c4a3fSrillig 	}
247ff5c4a3fSrillig }
248ff5c4a3fSrillig 
249ff5c4a3fSrillig void
250d40c8c6bSrillig debug_buffers(const char *descr)
251ff5c4a3fSrillig {
252d40c8c6bSrillig 	if (lab.len > 0 || code.len > 0 || com.len > 0) {
253d40c8c6bSrillig 		debug_printf("%s:", descr);
254fe5b389bSrillig 		debug_print_buf("label", &lab);
255fe5b389bSrillig 		debug_print_buf("code", &code);
256fe5b389bSrillig 		debug_print_buf("comment", &com);
257dd953560Srillig 		debug_blank_line();
258ff5c4a3fSrillig 	}
259d40c8c6bSrillig }
260ff5c4a3fSrillig 
26189f19ae3Srillig static void
262b520fe89Srillig debug_ps_bool_member(const char *name, bool prev, bool curr)
26389f19ae3Srillig {
2645cfa7113Srillig 	if (!state.ps_first && curr != prev) {
26589f19ae3Srillig 		char diff = " -+x"[(prev ? 1 : 0) + (curr ? 2 : 0)];
266d40c8c6bSrillig 		debug_println("\t\t%s: [%c]", name, diff);
26789f19ae3Srillig 	} else if (config.full_parser_state || state.ps_first)
268d40c8c6bSrillig 		debug_println("\t\t%s: [%c]", name, curr ? 'x' : ' ');
26989f19ae3Srillig }
27089f19ae3Srillig 
27189f19ae3Srillig static void
272b520fe89Srillig debug_ps_int_member(const char *name, int prev, int curr)
27389f19ae3Srillig {
2745cfa7113Srillig 	if (!state.ps_first && curr != prev)
275d40c8c6bSrillig 		debug_println("\t\t%s: %d -> %d", name, prev, curr);
27689f19ae3Srillig 	else if (config.full_parser_state || state.ps_first)
277d40c8c6bSrillig 		debug_println("\t\t%s: %d", name, curr);
27889f19ae3Srillig }
27989f19ae3Srillig 
28089f19ae3Srillig static void
281b520fe89Srillig debug_ps_enum_member(const char *name, const char *prev, const char *curr)
28289f19ae3Srillig {
2835cfa7113Srillig 	if (!state.ps_first && strcmp(prev, curr) != 0)
284d40c8c6bSrillig 		debug_println("\t\t%s: %s -> %s", name, prev, curr);
28589f19ae3Srillig 	else if (config.full_parser_state || state.ps_first)
286d40c8c6bSrillig 		debug_println("\t\t%s: %s", name, curr);
28789f19ae3Srillig }
288ff5c4a3fSrillig 
289*8af25fb9Srillig static void
290*8af25fb9Srillig debug_ps_str_member(const char *name,
291*8af25fb9Srillig     void (*to_string)(struct buffer *, const struct parser_state *))
292ff5c4a3fSrillig {
293*8af25fb9Srillig 	static struct buffer prev_buf;
294*8af25fb9Srillig 	static struct buffer curr_buf;
295ff5c4a3fSrillig 
296*8af25fb9Srillig 	buf_clear(&prev_buf);
297*8af25fb9Srillig 	to_string(&prev_buf, &state.prev_ps);
298*8af25fb9Srillig 	buf_clear(&curr_buf);
299*8af25fb9Srillig 	to_string(&curr_buf, &ps);
300*8af25fb9Srillig 
301*8af25fb9Srillig 	if (!state.ps_first && strcmp(prev_buf.s, curr_buf.s) != 0)
302*8af25fb9Srillig 		debug_println("\t\t%s: %s -> %s",
303*8af25fb9Srillig 		    name, prev_buf.s, curr_buf.s);
304*8af25fb9Srillig 	else if (config.full_parser_state || state.ps_first)
305*8af25fb9Srillig 		debug_println("\t\t%s: %s", name, curr_buf.s);
306ff5c4a3fSrillig }
307ff5c4a3fSrillig 
308ff5c4a3fSrillig static void
309*8af25fb9Srillig ps_di_stack_to_string(struct buffer *buf, const struct parser_state *s)
310ff5c4a3fSrillig {
311*8af25fb9Srillig 	for (int i = 0; i < s->decl_level; i++) {
312*8af25fb9Srillig 		char str[64];
313*8af25fb9Srillig 		snprintf(str, sizeof(str), "%s%d",
314*8af25fb9Srillig 			 i > 0 ? " " : "", s->di_stack[i]);
315*8af25fb9Srillig 		buf_add_str(buf, str);
316ff5c4a3fSrillig 	}
317*8af25fb9Srillig 	if (s->decl_level == 0)
318*8af25fb9Srillig 		buf_add_str(buf, "none");
319e174834cSrillig }
320e174834cSrillig 
321e174834cSrillig static void
322*8af25fb9Srillig ps_paren_to_string(struct buffer *buf, const struct parser_state *s)
323e174834cSrillig {
324*8af25fb9Srillig 	for (size_t i = 0; i < s->paren.len; i++) {
325*8af25fb9Srillig 		buf_add_str(buf, i > 0 ? "  " : "");
326*8af25fb9Srillig 		buf_add_str(buf, paren_level_cast_name[s->paren.item[i].cast]);
327*8af25fb9Srillig 		char str[64];
328*8af25fb9Srillig 		snprintf(str, sizeof(str), " %d", s->paren.item[i].indent);
329*8af25fb9Srillig 		buf_add_str(buf, str);
330*8af25fb9Srillig 	}
331*8af25fb9Srillig 	if (s->paren.len == 0)
332*8af25fb9Srillig 		buf_add_str(buf, "none");
333*8af25fb9Srillig }
334e174834cSrillig 
335*8af25fb9Srillig void
336*8af25fb9Srillig ps_psyms_to_string(struct buffer *buf, const struct parser_state *s)
337*8af25fb9Srillig {
338*8af25fb9Srillig 	for (size_t i = 0; i < s->psyms.len; i++) {
339*8af25fb9Srillig 		char num[64];
340*8af25fb9Srillig 		snprintf(num, sizeof(num), "%s%d ",
341*8af25fb9Srillig 		    i > 0 ? "  " : "", s->psyms.ind_level[i]);
342*8af25fb9Srillig 		buf_add_str(buf, num);
343*8af25fb9Srillig 		buf_add_str(buf, psym_name[s->psyms.sym[i]]);
344*8af25fb9Srillig 	}
345e174834cSrillig }
346e174834cSrillig 
34789f19ae3Srillig #define debug_ps_bool(name) \
348b520fe89Srillig 	debug_ps_bool_member(#name, state.prev_ps.name, ps.name)
34989f19ae3Srillig #define debug_ps_int(name) \
350b520fe89Srillig 	debug_ps_int_member(#name, state.prev_ps.name, ps.name)
35189f19ae3Srillig #define debug_ps_enum(name, names) \
352b520fe89Srillig         debug_ps_enum_member(#name, (names)[state.prev_ps.name], \
353b520fe89Srillig 	    (names)[ps.name])
354*8af25fb9Srillig #define debug_ps_str(name, to_string) \
355*8af25fb9Srillig         debug_ps_str_member((/* LINTED 129 */(void)&ps.name, #name), to_string)
35689f19ae3Srillig 
357ff5c4a3fSrillig void
358fe5b389bSrillig debug_parser_state(void)
359ff5c4a3fSrillig {
360fe5b389bSrillig 	debug_blank_line();
3612a46ceffSrillig 
362d40c8c6bSrillig 	state.heading1 = "parser state";
363d40c8c6bSrillig 	state.heading2 = "token classification";
3645cfa7113Srillig 	debug_ps_enum(prev_lsym, lsym_name);
3652a46ceffSrillig 	debug_ps_bool(in_stmt_or_decl);
3662a46ceffSrillig 	debug_ps_bool(in_decl);
367c4d54aecSrillig 	debug_ps_bool(in_typedef_decl);
368338e471fSrillig 	debug_ps_bool(in_var_decl);
369338e471fSrillig 	debug_ps_bool(in_init);
370338e471fSrillig 	debug_ps_int(init_level);
371645d5d22Srillig 	debug_ps_bool(line_has_func_def);
3722a46ceffSrillig 	debug_ps_bool(in_func_def_params);
373338e471fSrillig 	debug_ps_bool(line_has_decl);
3742a46ceffSrillig 	debug_ps_enum(lbrace_kind, psym_name);
375338e471fSrillig 	debug_ps_enum(spaced_expr_psym, psym_name);
376338e471fSrillig 	debug_ps_bool(seen_case);
377ae40ebbcSrillig 	debug_ps_bool(prev_paren_was_cast);
378338e471fSrillig 	debug_ps_int(quest_level);
3792a46ceffSrillig 
380d40c8c6bSrillig 	state.heading2 = "indentation of statements and declarations";
3812a46ceffSrillig 	debug_ps_int(ind_level);
3822a46ceffSrillig 	debug_ps_int(ind_level_follow);
383*8af25fb9Srillig 	debug_ps_str(psyms, ps_psyms_to_string);
3845a6a9cd4Srillig 	debug_ps_bool(line_is_stmt_cont);
3852a46ceffSrillig 	debug_ps_int(decl_level);
386*8af25fb9Srillig 	debug_ps_str(di_stack, ps_di_stack_to_string);
3872a46ceffSrillig 	debug_ps_bool(decl_indent_done);
3882a46ceffSrillig 	debug_ps_int(decl_ind);
3892a46ceffSrillig 	debug_ps_bool(tabs_to_var);
3902a46ceffSrillig 	debug_ps_enum(extra_expr_indent, extra_expr_indent_name);
3912a46ceffSrillig 
392d40c8c6bSrillig 	state.heading2 = "spacing inside a statement or declaration";
3932a46ceffSrillig 	debug_ps_bool(next_unary);
394ff5c4a3fSrillig 	debug_ps_bool(want_blank);
3954e81574bSrillig 	debug_ps_int(ind_paren_level);
396*8af25fb9Srillig 	debug_ps_str(paren, ps_paren_to_string);
397ff5c4a3fSrillig 
398d40c8c6bSrillig 	state.heading2 = "indentation of comments";
399ed7b4359Srillig 	debug_ps_int(comment_ind);
400ed7b4359Srillig 	debug_ps_int(comment_shift);
40137a17710Srillig 	debug_ps_bool(comment_cont);
402ff5c4a3fSrillig 
403d40c8c6bSrillig 	state.heading2 = "vertical spacing";
4042a46ceffSrillig 	debug_ps_bool(break_after_comma);
405e914aa7bSrillig 	debug_ps_enum(newline, newline_name);
406ae0013d2Srillig 	debug_ps_enum(declaration, declaration_name);
4072261e976Srillig 	debug_ps_bool(blank_line_after_decl);
408f6c6195cSrillig 	debug_ps_enum(badp, badp_name);
409ff5c4a3fSrillig 
410d40c8c6bSrillig 	state.heading1 = NULL;
411d40c8c6bSrillig 	state.heading2 = NULL;
412fe5b389bSrillig 	debug_blank_line();
413ff5c4a3fSrillig 
4141fe8cbaaSrillig 	parser_state_free(&state.prev_ps);
4151fe8cbaaSrillig 	parser_state_back_up(&state.prev_ps);
41689f19ae3Srillig 	state.ps_first = false;
417ff5c4a3fSrillig }
418ff5c4a3fSrillig #endif
419