indent.c revision 1.227 1 /* $NetBSD: indent.c,v 1.227 2021/11/19 20:04:02 rillig Exp $ */
2
3 /*-
4 * SPDX-License-Identifier: BSD-4-Clause
5 *
6 * Copyright (c) 1985 Sun Microsystems, Inc.
7 * Copyright (c) 1976 Board of Trustees of the University of Illinois.
8 * Copyright (c) 1980, 1993
9 * The Regents of the University of California. All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of
22 * California, Berkeley and 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
25 * without specific prior written permission.
26 *
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
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
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
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
37 * SUCH DAMAGE.
38 */
39
40 #if 0
41 static char sccsid[] = "@(#)indent.c 5.17 (Berkeley) 6/7/93";
42 #endif
43
44 #include <sys/cdefs.h>
45 #if defined(__NetBSD__)
46 __RCSID("$NetBSD: indent.c,v 1.227 2021/11/19 20:04:02 rillig Exp $");
47 #elif defined(__FreeBSD__)
48 __FBSDID("$FreeBSD: head/usr.bin/indent/indent.c 340138 2018-11-04 19:24:49Z oshogbo $");
49 #endif
50
51 #include <sys/param.h>
52 #if HAVE_CAPSICUM
53 #include <sys/capsicum.h>
54 #include <capsicum_helpers.h>
55 #endif
56 #include <assert.h>
57 #include <ctype.h>
58 #include <err.h>
59 #include <errno.h>
60 #include <fcntl.h>
61 #include <stdarg.h>
62 #include <stdio.h>
63 #include <stdlib.h>
64 #include <string.h>
65 #include <unistd.h>
66
67 #include "indent.h"
68
69 struct options opt = {
70 .brace_same_line = true,
71 .comment_delimiter_on_blankline = true,
72 .cuddle_else = true,
73 .comment_column = 33,
74 .decl_indent = 16,
75 .else_if = true,
76 .function_brace_split = true,
77 .format_col1_comments = true,
78 .format_block_comments = true,
79 .indent_parameters = true,
80 .indent_size = 8,
81 .local_decl_indent = -1,
82 .lineup_to_parens = true,
83 .procnames_start_line = true,
84 .star_comment_cont = true,
85 .tabsize = 8,
86 .max_line_length = 78,
87 .use_tabs = true,
88 };
89
90 struct parser_state ps;
91
92 struct buffer token;
93
94 struct buffer lab;
95 struct buffer code;
96 struct buffer com;
97
98 bool found_err;
99 int blank_lines_to_output;
100 bool blank_line_before;
101 bool blank_line_after;
102 bool break_comma;
103 float case_ind;
104 bool had_eof;
105 int line_no = 1;
106 bool inhibit_formatting;
107
108 static int ifdef_level;
109 static struct parser_state state_stack[5];
110
111 FILE *input;
112 FILE *output;
113
114 static const char *in_name = "Standard Input";
115 static const char *out_name = "Standard Output";
116 static const char *backup_suffix = ".BAK";
117 static char bakfile[MAXPATHLEN] = "";
118
119 #if HAVE_CAPSICUM
120 static void
121 init_capsicum(void)
122 {
123 cap_rights_t rights;
124
125 /* Restrict input/output descriptors and enter Capsicum sandbox. */
126 cap_rights_init(&rights, CAP_FSTAT, CAP_WRITE);
127 if (caph_rights_limit(fileno(output), &rights) < 0)
128 err(EXIT_FAILURE, "unable to limit rights for %s", out_name);
129 cap_rights_init(&rights, CAP_FSTAT, CAP_READ);
130 if (caph_rights_limit(fileno(input), &rights) < 0)
131 err(EXIT_FAILURE, "unable to limit rights for %s", in_name);
132 if (caph_enter() < 0)
133 err(EXIT_FAILURE, "unable to enter capability mode");
134 }
135 #endif
136
137 static void
138 buf_init(struct buffer *buf)
139 {
140 size_t size = 200;
141 buf->buf = xmalloc(size);
142 buf->l = buf->buf + size - 5 /* safety margin */;
143 buf->s = buf->buf + 1; /* allow accessing buf->e[-1] */
144 buf->e = buf->s;
145 buf->buf[0] = ' ';
146 buf->buf[1] = '\0';
147 }
148
149 static size_t
150 buf_len(const struct buffer *buf)
151 {
152 return (size_t)(buf->e - buf->s);
153 }
154
155 void
156 buf_expand(struct buffer *buf, size_t add_size)
157 {
158 size_t new_size = (size_t)(buf->l - buf->s) + 400 + add_size;
159 size_t len = buf_len(buf);
160 buf->buf = xrealloc(buf->buf, new_size);
161 buf->l = buf->buf + new_size - 5;
162 buf->s = buf->buf + 1;
163 buf->e = buf->s + len;
164 /* At this point, the buffer may not be null-terminated anymore. */
165 }
166
167 static void
168 buf_reserve(struct buffer *buf, size_t n)
169 {
170 if (n >= (size_t)(buf->l - buf->e))
171 buf_expand(buf, n);
172 }
173
174 static void
175 buf_add_char(struct buffer *buf, char ch)
176 {
177 buf_reserve(buf, 1);
178 *buf->e++ = ch;
179 }
180
181 static void
182 buf_add_buf(struct buffer *buf, const struct buffer *add)
183 {
184 size_t len = buf_len(add);
185 buf_reserve(buf, len);
186 memcpy(buf->e, add->s, len);
187 buf->e += len;
188 }
189
190 static void
191 buf_terminate(struct buffer *buf)
192 {
193 buf_reserve(buf, 1);
194 *buf->e = '\0';
195 }
196
197 static void
198 buf_reset(struct buffer *buf)
199 {
200 buf->e = buf->s;
201 }
202
203 void
204 diag(int level, const char *msg, ...)
205 {
206 va_list ap;
207
208 if (level != 0)
209 found_err = true;
210
211 va_start(ap, msg);
212 fprintf(stderr, "%s: %s:%d: ",
213 level == 0 ? "warning" : "error", in_name, line_no);
214 vfprintf(stderr, msg, ap);
215 fprintf(stderr, "\n");
216 va_end(ap);
217 }
218
219 static void
220 search_stmt_newline(bool *force_nl)
221 {
222 inp_comment_init_newline();
223 inp_comment_add_char('\n');
224 debug_inp(__func__);
225
226 line_no++;
227
228 /*
229 * We may have inherited a force_nl == true from the previous token (like
230 * a semicolon). But once we know that a newline has been scanned in this
231 * loop, force_nl should be false.
232 *
233 * However, the force_nl == true must be preserved if newline is never
234 * scanned in this loop, so this assignment cannot be done earlier.
235 */
236 *force_nl = false;
237 }
238
239 static void
240 search_stmt_comment(void)
241 {
242 inp_comment_init_comment();
243 inp_comment_add_range(token.s, token.e);
244 if (token.e[-1] == '/') {
245 while (inp_peek() != '\n')
246 inp_comment_add_char(inp_next());
247 debug_inp("search_stmt_comment end C99");
248 } else {
249 while (!inp_comment_complete_block())
250 inp_comment_add_char(inp_next());
251 debug_inp("search_stmt_comment end block");
252 }
253 }
254
255 static bool
256 search_stmt_lbrace(void)
257 {
258 /*
259 * Put KNF-style lbraces before the buffered up tokens and jump out of
260 * this loop in order to avoid copying the token again.
261 */
262 if (inp_comment_seen() && opt.brace_same_line) {
263 inp_comment_insert_lbrace();
264 /*
265 * Originally the lbrace may have been alone on its own line, but it
266 * will be moved into "the else's line", so if there was a newline
267 * resulting from the "{" before, it must be scanned now and ignored.
268 */
269 while (isspace((unsigned char)inp_peek())) {
270 inp_skip();
271 if (inp_peek() == '\n')
272 break;
273 }
274 debug_inp(__func__);
275 return true;
276 }
277 return false;
278 }
279
280 static bool
281 search_stmt_other(lexer_symbol lsym, bool *force_nl,
282 bool comment_buffered, bool last_else)
283 {
284 bool remove_newlines;
285
286 remove_newlines =
287 /* "} else" */
288 (lsym == lsym_else && code.e != code.s && code.e[-1] == '}')
289 /* "else if" */
290 || (lsym == lsym_if && last_else && opt.else_if);
291 if (remove_newlines)
292 *force_nl = false;
293
294 if (!inp_comment_seen()) {
295 ps.search_stmt = false;
296 return false;
297 }
298
299 debug_inp(__func__);
300 inp_comment_rtrim();
301
302 if (opt.swallow_optional_blanklines ||
303 (!comment_buffered && remove_newlines)) {
304 *force_nl = !remove_newlines;
305 inp_comment_rtrim_newline();
306 }
307
308 if (*force_nl) { /* if we should insert a nl here, put it into
309 * the buffer */
310 *force_nl = false;
311 --line_no; /* this will be re-increased when the newline
312 * is read from the buffer */
313 inp_comment_add_char('\n');
314 inp_comment_add_char(' ');
315 if (opt.verbose) /* warn if the line was not already broken */
316 diag(0, "Line broken");
317 }
318
319 for (const char *t_ptr = token.s; *t_ptr != '\0'; ++t_ptr)
320 inp_comment_add_char(*t_ptr);
321 debug_inp("search_stmt_other end");
322 return true;
323 }
324
325 static void
326 switch_buffer(void)
327 {
328 ps.search_stmt = false;
329 inp_comment_add_char(' '); /* add trailing blank, just in case */
330 inp_from_comment();
331 }
332
333 static void
334 search_stmt_lookahead(lexer_symbol *lsym)
335 {
336 if (*lsym == lsym_eof)
337 return;
338
339 /*
340 * The only intended purpose of calling lexi() below is to categorize the
341 * next token in order to decide whether to continue buffering forthcoming
342 * tokens. Once the buffering is over, lexi() will be called again
343 * elsewhere on all of the tokens - this time for normal processing.
344 *
345 * Calling it for this purpose is a bug, because lexi() also changes the
346 * parser state and discards leading whitespace, which is needed mostly
347 * for comment-related considerations.
348 *
349 * Work around the former problem by giving lexi() a copy of the current
350 * parser state and discard it if the call turned out to be just a
351 * lookahead.
352 *
353 * Work around the latter problem by copying all whitespace characters
354 * into the buffer so that the later lexi() call will read them.
355 */
356 if (inp_comment_seen()) {
357 while (ch_isblank(inp_peek()))
358 inp_comment_add_char(inp_next());
359 debug_inp(__func__);
360 }
361
362 struct parser_state backup_ps = ps;
363 debug_println("made backup of parser state");
364 *lsym = lexi();
365 if (*lsym == lsym_newline || *lsym == lsym_form_feed ||
366 *lsym == lsym_comment || ps.search_stmt) {
367 ps = backup_ps;
368 debug_println("rolled back parser state");
369 }
370 }
371
372 /*
373 * Move newlines and comments following an 'if (expr)', 'while (expr)',
374 * 'else', etc. up to the start of the following statement to a buffer. This
375 * allows proper handling of both kinds of brace placement (-br, -bl) and
376 * "cuddling else" (-ce).
377 */
378 static void
379 search_stmt(lexer_symbol *lsym, bool *force_nl, bool *last_else)
380 {
381 bool comment_buffered = false;
382
383 while (ps.search_stmt) {
384 switch (*lsym) {
385 case lsym_newline:
386 search_stmt_newline(force_nl);
387 break;
388 case lsym_form_feed:
389 /* XXX: Is simply removed from the source code. */
390 break;
391 case lsym_comment:
392 search_stmt_comment();
393 comment_buffered = true;
394 break;
395 case lsym_lbrace:
396 if (search_stmt_lbrace())
397 goto switch_buffer;
398 /* FALLTHROUGH */
399 default:
400 if (!search_stmt_other(*lsym, force_nl, comment_buffered,
401 *last_else))
402 return;
403 switch_buffer:
404 switch_buffer();
405 }
406 search_stmt_lookahead(lsym);
407 }
408
409 *last_else = false;
410 }
411
412 static void
413 main_init_globals(void)
414 {
415 inp_init();
416
417 buf_init(&token);
418
419 buf_init(&lab);
420 buf_init(&code);
421 buf_init(&com);
422
423 ps.s_sym[0] = psym_stmt_list;
424 ps.prev_token = lsym_semicolon;
425 ps.next_col_1 = true;
426
427 const char *suffix = getenv("SIMPLE_BACKUP_SUFFIX");
428 if (suffix != NULL)
429 backup_suffix = suffix;
430 }
431
432 /*
433 * Copy the input file to the backup file, then make the backup file the input
434 * and the original input file the output.
435 */
436 static void
437 bakcopy(void)
438 {
439 ssize_t n;
440 int bak_fd;
441 char buff[8 * 1024];
442
443 const char *last_slash = strrchr(in_name, '/');
444 snprintf(bakfile, sizeof(bakfile), "%s%s",
445 last_slash != NULL ? last_slash + 1 : in_name, backup_suffix);
446
447 /* copy in_name to backup file */
448 bak_fd = creat(bakfile, 0600);
449 if (bak_fd < 0)
450 err(1, "%s", bakfile);
451
452 while ((n = read(fileno(input), buff, sizeof(buff))) > 0)
453 if (write(bak_fd, buff, (size_t)n) != n)
454 err(1, "%s", bakfile);
455 if (n < 0)
456 err(1, "%s", in_name);
457
458 close(bak_fd);
459 (void)fclose(input);
460
461 /* re-open backup file as the input file */
462 input = fopen(bakfile, "r");
463 if (input == NULL)
464 err(1, "%s", bakfile);
465 /* now the original input file will be the output */
466 output = fopen(in_name, "w");
467 if (output == NULL) {
468 unlink(bakfile);
469 err(1, "%s", in_name);
470 }
471 }
472
473 static void
474 main_load_profiles(int argc, char **argv)
475 {
476 const char *profile_name = NULL;
477
478 for (int i = 1; i < argc; ++i) {
479 const char *arg = argv[i];
480
481 if (strcmp(arg, "-npro") == 0)
482 return;
483 if (arg[0] == '-' && arg[1] == 'P' && arg[2] != '\0')
484 profile_name = arg + 2;
485 }
486 load_profiles(profile_name);
487 }
488
489 static void
490 main_parse_command_line(int argc, char **argv)
491 {
492 for (int i = 1; i < argc; ++i) {
493 const char *arg = argv[i];
494
495 if (arg[0] == '-') {
496 set_option(arg, "Command line");
497
498 } else if (input == NULL) {
499 in_name = arg;
500 if ((input = fopen(in_name, "r")) == NULL)
501 err(1, "%s", in_name);
502
503 } else if (output == NULL) {
504 out_name = arg;
505 if (strcmp(in_name, out_name) == 0)
506 errx(1, "input and output files must be different");
507 if ((output = fopen(out_name, "w")) == NULL)
508 err(1, "%s", out_name);
509
510 } else
511 errx(1, "too many arguments: %s", arg);
512 }
513
514 if (input == NULL) {
515 input = stdin;
516 output = stdout;
517 } else if (output == NULL) {
518 out_name = in_name;
519 bakcopy();
520 }
521
522 if (opt.comment_column <= 1)
523 opt.comment_column = 2; /* don't put normal comments before column 2 */
524 if (opt.block_comment_max_line_length <= 0)
525 opt.block_comment_max_line_length = opt.max_line_length;
526 if (opt.local_decl_indent < 0) /* if not specified by user, set this */
527 opt.local_decl_indent = opt.decl_indent;
528 if (opt.decl_comment_column <= 0) /* if not specified by user, set this */
529 opt.decl_comment_column = opt.ljust_decl
530 ? (opt.comment_column <= 10 ? 2 : opt.comment_column - 8)
531 : opt.comment_column;
532 if (opt.continuation_indent == 0)
533 opt.continuation_indent = opt.indent_size;
534 }
535
536 static void
537 main_prepare_parsing(void)
538 {
539 inp_read_line();
540
541 int ind = 0;
542 for (const char *p = inp_p();; p++) {
543 if (*p == ' ')
544 ind++;
545 else if (*p == '\t')
546 ind = next_tab(ind);
547 else
548 break;
549 }
550
551 if (ind >= opt.indent_size)
552 ps.ind_level = ps.ind_level_follow = ind / opt.indent_size;
553 }
554
555 static void
556 code_add_decl_indent(int decl_ind, bool tabs_to_var)
557 {
558 int base_ind = ps.ind_level * opt.indent_size;
559 int ind = base_ind + (int)buf_len(&code);
560 int target_ind = base_ind + decl_ind;
561 char *orig_code_e = code.e;
562
563 if (tabs_to_var)
564 for (int next; (next = next_tab(ind)) <= target_ind; ind = next)
565 buf_add_char(&code, '\t');
566
567 for (; ind < target_ind; ind++)
568 buf_add_char(&code, ' ');
569
570 if (code.e == orig_code_e && ps.want_blank) {
571 buf_add_char(&code, ' ');
572 ps.want_blank = false;
573 }
574 }
575
576 static void __attribute__((__noreturn__))
577 process_eof(void)
578 {
579 if (lab.s != lab.e || code.s != code.e || com.s != com.e)
580 dump_line();
581
582 if (ps.tos > 1) /* check for balanced braces */
583 diag(1, "Stuff missing from end of file");
584
585 if (opt.verbose) {
586 printf("There were %d output lines and %d comments\n",
587 ps.stats.lines, ps.stats.comments);
588 printf("(Lines with comments)/(Lines with code): %6.3f\n",
589 (1.0 * ps.stats.comment_lines) / ps.stats.code_lines);
590 }
591
592 fflush(output);
593 exit(found_err ? EXIT_FAILURE : EXIT_SUCCESS);
594 }
595
596 static void
597 maybe_break_line(lexer_symbol lsym, bool *force_nl)
598 {
599 if (!*force_nl)
600 return;
601 if (lsym == lsym_semicolon)
602 return;
603 else if (lsym == lsym_lbrace && opt.brace_same_line)
604 return;
605
606 if (opt.verbose)
607 diag(0, "Line broken");
608 dump_line();
609 ps.want_blank = false;
610 *force_nl = false;
611 }
612
613 static void
614 move_com_to_code(void)
615 {
616 buf_add_char(&code, ' ');
617 buf_add_buf(&code, &com);
618 buf_add_char(&code, ' ');
619 buf_terminate(&code);
620 buf_reset(&com);
621 ps.want_blank = false;
622 }
623
624 static void
625 process_form_feed(void)
626 {
627 dump_line_ff();
628 ps.want_blank = false;
629 }
630
631 static void
632 process_newline(void)
633 {
634 if (ps.prev_token == lsym_comma && ps.p_l_follow == 0 && !ps.block_init &&
635 !opt.break_after_comma && break_comma &&
636 com.s == com.e)
637 goto stay_in_line;
638
639 dump_line();
640 ps.want_blank = false;
641
642 stay_in_line:
643 ++line_no;
644 }
645
646 static bool
647 want_blank_before_lparen(void)
648 {
649 if (!ps.want_blank)
650 return false;
651 if (opt.proc_calls_space)
652 return true;
653 if (ps.prev_token == lsym_rparen_or_rbracket)
654 return false;
655 if (ps.prev_token == lsym_offsetof)
656 return false;
657 if (ps.prev_token == lsym_sizeof)
658 return opt.blank_after_sizeof;
659 if (ps.prev_token == lsym_word || ps.prev_token == lsym_funcname)
660 return false;
661 return true;
662 }
663
664 static void
665 process_lparen_or_lbracket(int decl_ind, bool tabs_to_var, bool spaced_expr)
666 {
667 if (++ps.p_l_follow == array_length(ps.paren_indents)) {
668 diag(0, "Reached internal limit of %zu unclosed parentheses",
669 array_length(ps.paren_indents));
670 ps.p_l_follow--;
671 }
672
673 if (token.s[0] == '(' && ps.in_decl
674 && !ps.block_init && !ps.decl_indent_done &&
675 !ps.is_function_definition && ps.paren_level == 0) {
676 /* function pointer declarations */
677 code_add_decl_indent(decl_ind, tabs_to_var);
678 ps.decl_indent_done = true;
679 } else if (want_blank_before_lparen())
680 *code.e++ = ' ';
681 ps.want_blank = false;
682 *code.e++ = token.s[0];
683
684 ps.paren_indents[ps.p_l_follow - 1] = (short)ind_add(0, code.s, code.e);
685 debug_println("paren_indents[%d] is now %d",
686 ps.p_l_follow - 1, ps.paren_indents[ps.p_l_follow - 1]);
687
688 if (spaced_expr && ps.p_l_follow == 1 && opt.extra_expr_indent
689 && ps.paren_indents[0] < 2 * opt.indent_size) {
690 ps.paren_indents[0] = (short)(2 * opt.indent_size);
691 debug_println("paren_indents[0] is now %d", ps.paren_indents[0]);
692 }
693
694 if (ps.init_or_struct && *token.s == '(' && ps.tos <= 2) {
695 /*
696 * this is a kluge to make sure that declarations will be aligned
697 * right if proc decl has an explicit type on it, i.e. "int a(x) {..."
698 */
699 parse(psym_semicolon); /* I said this was a kluge... */
700 ps.init_or_struct = false;
701 }
702
703 /* parenthesized type following sizeof or offsetof is not a cast */
704 if (ps.prev_token == lsym_offsetof || ps.prev_token == lsym_sizeof)
705 ps.not_cast_mask |= 1 << ps.p_l_follow;
706 }
707
708 static void
709 process_rparen_or_rbracket(bool *spaced_expr, bool *force_nl, stmt_head hd)
710 {
711 if ((ps.cast_mask & (1 << ps.p_l_follow) & ~ps.not_cast_mask) != 0) {
712 ps.next_unary = true;
713 ps.cast_mask &= (1 << ps.p_l_follow) - 1;
714 ps.want_blank = opt.space_after_cast;
715 } else
716 ps.want_blank = true;
717 ps.not_cast_mask &= (1 << ps.p_l_follow) - 1;
718
719 if (ps.p_l_follow > 0)
720 ps.p_l_follow--;
721 else
722 diag(0, "Extra '%c'", *token.s);
723
724 if (code.e == code.s) /* if the paren starts the line */
725 ps.paren_level = ps.p_l_follow; /* then indent it */
726
727 *code.e++ = token.s[0];
728
729 if (*spaced_expr && ps.p_l_follow == 0) { /* check for end of 'if
730 * (...)', or some such */
731 *spaced_expr = false;
732 *force_nl = true; /* must force newline after if */
733 ps.next_unary = true;
734 ps.in_stmt = false; /* don't use stmt continuation indentation */
735
736 parse_stmt_head(hd);
737 }
738
739 /*
740 * This should ensure that constructs such as main(){...} and int[]{...}
741 * have their braces put in the right place.
742 */
743 ps.search_stmt = opt.brace_same_line;
744 }
745
746 static bool
747 want_blank_before_unary_op(void)
748 {
749 if (ps.want_blank)
750 return true;
751 if (token.s[0] == '+' || token.s[0] == '-')
752 return code.e > code.s && code.e[-1] == token.s[0];
753 return false;
754 }
755
756 static void
757 process_unary_op(int decl_ind, bool tabs_to_var)
758 {
759 if (!ps.decl_indent_done && ps.in_decl && !ps.block_init &&
760 !ps.is_function_definition && ps.paren_level == 0) {
761 /* pointer declarations */
762 code_add_decl_indent(decl_ind - (int)buf_len(&token), tabs_to_var);
763 ps.decl_indent_done = true;
764 } else if (want_blank_before_unary_op())
765 *code.e++ = ' ';
766
767 buf_add_buf(&code, &token);
768 ps.want_blank = false;
769 }
770
771 static void
772 process_binary_op(void)
773 {
774 if (buf_len(&code) > 0)
775 buf_add_char(&code, ' ');
776 buf_add_buf(&code, &token);
777 ps.want_blank = true;
778 }
779
780 static void
781 process_postfix_op(void)
782 {
783 *code.e++ = token.s[0];
784 *code.e++ = token.s[1];
785 ps.want_blank = true;
786 }
787
788 static void
789 process_question(int *quest_level)
790 {
791 (*quest_level)++;
792 if (ps.want_blank)
793 *code.e++ = ' ';
794 *code.e++ = '?';
795 ps.want_blank = true;
796 }
797
798 static void
799 process_colon(int *quest_level, bool *force_nl, bool *seen_case)
800 {
801 if (*quest_level > 0) { /* part of a '?:' operator */
802 --*quest_level;
803 if (ps.want_blank)
804 *code.e++ = ' ';
805 *code.e++ = ':';
806 ps.want_blank = true;
807 return;
808 }
809
810 if (ps.init_or_struct) { /* bit-field */
811 *code.e++ = ':';
812 ps.want_blank = false;
813 return;
814 }
815
816 buf_add_buf(&lab, &code); /* 'case' or 'default' or named label */
817 buf_add_char(&lab, ':');
818 buf_terminate(&lab);
819 buf_reset(&code);
820
821 ps.in_stmt = false;
822 ps.is_case_label = *seen_case;
823 *force_nl = *seen_case;
824 *seen_case = false;
825 ps.want_blank = false;
826 }
827
828 static void
829 process_semicolon(bool *seen_case, int *quest_level, int decl_ind,
830 bool tabs_to_var, bool *spaced_expr, stmt_head hd, bool *force_nl)
831 {
832 if (ps.decl_level == 0)
833 ps.init_or_struct = false;
834 *seen_case = false; /* these will only need resetting in an error */
835 *quest_level = 0;
836 if (ps.prev_token == lsym_rparen_or_rbracket)
837 ps.in_parameter_declaration = false;
838 ps.cast_mask = 0;
839 ps.not_cast_mask = 0;
840 ps.block_init = false;
841 ps.block_init_level = 0;
842 ps.just_saw_decl--;
843
844 if (ps.in_decl && code.s == code.e && !ps.block_init &&
845 !ps.decl_indent_done && ps.paren_level == 0) {
846 /* indent stray semicolons in declarations */
847 code_add_decl_indent(decl_ind - 1, tabs_to_var);
848 ps.decl_indent_done = true;
849 }
850
851 ps.in_decl = ps.decl_level > 0; /* if we were in a first level
852 * structure declaration before, we
853 * aren't anymore */
854
855 if ((!*spaced_expr || hd != hd_for) && ps.p_l_follow > 0) {
856
857 /*
858 * There were unbalanced parentheses in the statement. It is a bit
859 * complicated, because the semicolon might be in a for statement.
860 */
861 diag(1, "Unbalanced parentheses");
862 ps.p_l_follow = 0;
863 if (*spaced_expr) { /* 'if', 'while', etc. */
864 *spaced_expr = false;
865 parse_stmt_head(hd);
866 }
867 }
868 *code.e++ = ';';
869 ps.want_blank = true;
870 ps.in_stmt = ps.p_l_follow > 0;
871
872 if (!*spaced_expr) { /* if not if for (;;) */
873 parse(psym_semicolon); /* let parser know about end of stmt */
874 *force_nl = true; /* force newline after an end of stmt */
875 }
876 }
877
878 static void
879 process_lbrace(bool *force_nl, bool *spaced_expr, stmt_head hd,
880 int *di_stack, int di_stack_cap, int *decl_ind)
881 {
882 ps.in_stmt = false; /* don't indent the {} */
883
884 if (!ps.block_init)
885 *force_nl = true; /* force other stuff on same line as '{' onto
886 * new line */
887 else if (ps.block_init_level <= 0)
888 ps.block_init_level = 1;
889 else
890 ps.block_init_level++;
891
892 if (code.s != code.e && !ps.block_init) {
893 if (!opt.brace_same_line) {
894 dump_line();
895 ps.want_blank = false;
896 } else if (ps.in_parameter_declaration && !ps.init_or_struct) {
897 ps.ind_level_follow = 0;
898 if (opt.function_brace_split) { /* dump the line prior to the
899 * brace ... */
900 dump_line();
901 ps.want_blank = false;
902 } else /* add a space between the decl and brace */
903 ps.want_blank = true;
904 }
905 }
906
907 if (ps.in_parameter_declaration)
908 blank_line_before = false;
909
910 if (ps.p_l_follow > 0) {
911 diag(1, "Unbalanced parentheses");
912 ps.p_l_follow = 0;
913 if (*spaced_expr) { /* check for unclosed 'if', 'for', etc. */
914 *spaced_expr = false;
915 parse_stmt_head(hd);
916 ps.ind_level = ps.ind_level_follow;
917 }
918 }
919
920 if (code.s == code.e)
921 ps.ind_stmt = false; /* don't indent the '{' itself */
922 if (ps.in_decl && ps.init_or_struct) {
923 di_stack[ps.decl_level] = *decl_ind;
924 if (++ps.decl_level == di_stack_cap) {
925 diag(0, "Reached internal limit of %d struct levels",
926 di_stack_cap);
927 ps.decl_level--;
928 }
929 } else {
930 ps.decl_on_line = false; /* we can't be in the middle of a
931 * declaration, so don't do special
932 * indentation of comments */
933 if (opt.blanklines_after_decl_at_top && ps.in_parameter_declaration)
934 blank_line_after = true;
935 ps.in_parameter_declaration = false;
936 ps.in_decl = false;
937 }
938
939 *decl_ind = 0;
940 parse(psym_lbrace);
941 if (ps.want_blank)
942 *code.e++ = ' ';
943 ps.want_blank = false;
944 *code.e++ = '{';
945 ps.just_saw_decl = 0;
946 }
947
948 static void
949 process_rbrace(bool *spaced_expr, int *decl_ind, const int *di_stack)
950 {
951 if (ps.s_sym[ps.tos] == psym_decl && !ps.block_init) {
952 /* semicolons can be omitted in declarations */
953 parse(psym_semicolon);
954 }
955
956 if (ps.p_l_follow > 0) { /* check for unclosed if, for, else. */
957 diag(1, "Unbalanced parentheses");
958 ps.p_l_follow = 0;
959 *spaced_expr = false;
960 }
961
962 ps.just_saw_decl = 0;
963 ps.block_init_level--;
964
965 if (code.s != code.e && !ps.block_init) { /* '}' must be first on line */
966 if (opt.verbose)
967 diag(0, "Line broken");
968 dump_line();
969 }
970
971 *code.e++ = '}';
972 ps.want_blank = true;
973 ps.in_stmt = ps.ind_stmt = false;
974
975 if (ps.decl_level > 0) { /* we are in multi-level structure declaration */
976 *decl_ind = di_stack[--ps.decl_level];
977 if (ps.decl_level == 0 && !ps.in_parameter_declaration) {
978 ps.just_saw_decl = 2;
979 *decl_ind = ps.ind_level == 0
980 ? opt.decl_indent : opt.local_decl_indent;
981 }
982 ps.in_decl = true;
983 }
984
985 blank_line_before = false;
986 parse(psym_rbrace);
987 ps.search_stmt = opt.cuddle_else
988 && ps.s_sym[ps.tos] == psym_if_expr_stmt
989 && ps.s_ind_level[ps.tos] >= ps.ind_level;
990
991 if (ps.tos <= 1 && opt.blanklines_after_procs && ps.decl_level <= 0)
992 blank_line_after = true;
993 }
994
995 static void
996 process_do(bool *force_nl, bool *last_else)
997 {
998 ps.in_stmt = false;
999
1000 if (code.e != code.s) { /* make sure this starts a line */
1001 if (opt.verbose)
1002 diag(0, "Line broken");
1003 dump_line();
1004 ps.want_blank = false;
1005 }
1006
1007 *force_nl = true; /* following stuff must go onto new line */
1008 *last_else = false;
1009 parse(psym_do);
1010 }
1011
1012 static void
1013 process_else(bool *force_nl, bool *last_else)
1014 {
1015 ps.in_stmt = false;
1016
1017 if (code.e > code.s && !(opt.cuddle_else && code.e[-1] == '}')) {
1018 if (opt.verbose)
1019 diag(0, "Line broken");
1020 dump_line(); /* make sure this starts a line */
1021 ps.want_blank = false;
1022 }
1023
1024 *force_nl = true; /* following stuff must go onto new line */
1025 *last_else = true;
1026 parse(psym_else);
1027 }
1028
1029 static void
1030 process_type(int *decl_ind, bool *tabs_to_var)
1031 {
1032 parse(psym_decl); /* let the parser worry about indentation */
1033
1034 if (ps.prev_token == lsym_rparen_or_rbracket && ps.tos <= 1) {
1035 if (code.s != code.e) {
1036 dump_line();
1037 ps.want_blank = false;
1038 }
1039 }
1040
1041 if (ps.in_parameter_declaration && opt.indent_parameters &&
1042 ps.decl_level == 0) {
1043 ps.ind_level = ps.ind_level_follow = 1;
1044 ps.ind_stmt = false;
1045 }
1046
1047 ps.init_or_struct = /* maybe */ true;
1048 ps.in_decl = ps.decl_on_line = ps.prev_token != lsym_typedef;
1049 if (ps.decl_level <= 0)
1050 ps.just_saw_decl = 2;
1051
1052 blank_line_before = false;
1053
1054 int len = (int)buf_len(&token) + 1;
1055 int ind = ps.ind_level == 0 || ps.decl_level > 0
1056 ? opt.decl_indent /* global variable or local member */
1057 : opt.local_decl_indent; /* local variable */
1058 *decl_ind = ind > 0 ? ind : len;
1059 *tabs_to_var = opt.use_tabs && ind > 0;
1060 }
1061
1062 static void
1063 process_ident(lexer_symbol lsym, int decl_ind, bool tabs_to_var,
1064 bool *spaced_expr, bool *force_nl, stmt_head hd)
1065 {
1066 if (ps.in_decl) {
1067 if (lsym == lsym_funcname) {
1068 ps.in_decl = false;
1069 if (opt.procnames_start_line && code.s != code.e) {
1070 *code.e = '\0';
1071 dump_line();
1072 } else if (ps.want_blank) {
1073 *code.e++ = ' ';
1074 }
1075 ps.want_blank = false;
1076
1077 } else if (!ps.block_init && !ps.decl_indent_done &&
1078 ps.paren_level == 0) {
1079 code_add_decl_indent(decl_ind, tabs_to_var);
1080 ps.decl_indent_done = true;
1081 ps.want_blank = false;
1082 }
1083
1084 } else if (*spaced_expr && ps.p_l_follow == 0) {
1085 *spaced_expr = false;
1086 *force_nl = true;
1087 ps.next_unary = true;
1088 ps.in_stmt = false;
1089 parse_stmt_head(hd);
1090 }
1091 }
1092
1093 static void
1094 copy_token(void)
1095 {
1096 if (ps.want_blank)
1097 buf_add_char(&code, ' ');
1098 buf_add_buf(&code, &token);
1099 }
1100
1101 static void
1102 process_string_prefix(void)
1103 {
1104 copy_token();
1105 ps.want_blank = false;
1106 }
1107
1108 static void
1109 process_period(void)
1110 {
1111 if (code.e > code.s && code.e[-1] == ',')
1112 *code.e++ = ' ';
1113 *code.e++ = '.';
1114 ps.want_blank = false;
1115 }
1116
1117 static void
1118 process_comma(int decl_ind, bool tabs_to_var, bool *force_nl)
1119 {
1120 ps.want_blank = code.s != code.e; /* only put blank after comma if comma
1121 * does not start the line */
1122
1123 if (ps.in_decl && !ps.is_function_definition && !ps.block_init &&
1124 !ps.decl_indent_done && ps.paren_level == 0) {
1125 /* indent leading commas and not the actual identifiers */
1126 code_add_decl_indent(decl_ind - 1, tabs_to_var);
1127 ps.decl_indent_done = true;
1128 }
1129
1130 *code.e++ = ',';
1131
1132 if (ps.p_l_follow == 0) {
1133 if (ps.block_init_level <= 0)
1134 ps.block_init = false;
1135 int varname_len = 8; /* rough estimate for the length of a typical
1136 * variable name */
1137 if (break_comma && (opt.break_after_comma ||
1138 ind_add(compute_code_indent(), code.s, code.e)
1139 >= opt.max_line_length - varname_len))
1140 *force_nl = true;
1141 }
1142 }
1143
1144 /* move the whole line to the 'label' buffer */
1145 static void
1146 read_preprocessing_line(void)
1147 {
1148 enum {
1149 PLAIN, STR, CHR, COMM
1150 } state;
1151
1152 buf_add_char(&lab, '#');
1153
1154 state = PLAIN;
1155 int com_start = 0, com_end = 0;
1156
1157 while (ch_isblank(inp_peek()))
1158 inp_skip();
1159
1160 while (inp_peek() != '\n' || (state == COMM && !had_eof)) {
1161 buf_reserve(&lab, 2);
1162 *lab.e++ = inp_next();
1163 switch (lab.e[-1]) {
1164 case '\\':
1165 if (state != COMM)
1166 *lab.e++ = inp_next();
1167 break;
1168 case '/':
1169 if (inp_peek() == '*' && state == PLAIN) {
1170 state = COMM;
1171 *lab.e++ = inp_next();
1172 com_start = (int)buf_len(&lab) - 2;
1173 }
1174 break;
1175 case '"':
1176 if (state == STR)
1177 state = PLAIN;
1178 else if (state == PLAIN)
1179 state = STR;
1180 break;
1181 case '\'':
1182 if (state == CHR)
1183 state = PLAIN;
1184 else if (state == PLAIN)
1185 state = CHR;
1186 break;
1187 case '*':
1188 if (inp_peek() == '/' && state == COMM) {
1189 state = PLAIN;
1190 *lab.e++ = inp_next();
1191 com_end = (int)buf_len(&lab);
1192 }
1193 break;
1194 }
1195 }
1196
1197 while (lab.e > lab.s && ch_isblank(lab.e[-1]))
1198 lab.e--;
1199 if (lab.e - lab.s == com_end && !inp_comment_seen()) {
1200 /* comment on preprocessor line */
1201 inp_comment_init_preproc();
1202 inp_comment_add_range(lab.s + com_start, lab.s + com_end);
1203 lab.e = lab.s + com_start;
1204 while (lab.e > lab.s && ch_isblank(lab.e[-1]))
1205 lab.e--;
1206 inp_comment_add_char(' '); /* add trailing blank, just in case */
1207 inp_from_comment();
1208 }
1209 buf_terminate(&lab);
1210 }
1211
1212 static void
1213 process_preprocessing(void)
1214 {
1215 if (com.s != com.e || lab.s != lab.e || code.s != code.e)
1216 dump_line();
1217
1218 read_preprocessing_line();
1219
1220 ps.is_case_label = false;
1221
1222 if (strncmp(lab.s, "#if", 3) == 0) { /* also ifdef, ifndef */
1223 if ((size_t)ifdef_level < array_length(state_stack))
1224 state_stack[ifdef_level++] = ps;
1225 else
1226 diag(1, "#if stack overflow");
1227
1228 } else if (strncmp(lab.s, "#el", 3) == 0) { /* else, elif */
1229 if (ifdef_level <= 0)
1230 diag(1, lab.s[3] == 'i' ? "Unmatched #elif" : "Unmatched #else");
1231 else
1232 ps = state_stack[ifdef_level - 1];
1233
1234 } else if (strncmp(lab.s, "#endif", 6) == 0) {
1235 if (ifdef_level <= 0)
1236 diag(1, "Unmatched #endif");
1237 else
1238 ifdef_level--;
1239
1240 } else {
1241 if (strncmp(lab.s + 1, "pragma", 6) != 0 &&
1242 strncmp(lab.s + 1, "error", 5) != 0 &&
1243 strncmp(lab.s + 1, "line", 4) != 0 &&
1244 strncmp(lab.s + 1, "undef", 5) != 0 &&
1245 strncmp(lab.s + 1, "define", 6) != 0 &&
1246 strncmp(lab.s + 1, "include", 7) != 0) {
1247 diag(1, "Unrecognized cpp directive");
1248 return;
1249 }
1250 }
1251
1252 if (opt.blanklines_around_conditional_compilation) {
1253 blank_line_after = true;
1254 blank_lines_to_output = 0;
1255 } else {
1256 blank_line_after = false;
1257 blank_line_before = false;
1258 }
1259
1260 /*
1261 * subsequent processing of the newline character will cause the line to
1262 * be printed
1263 */
1264 }
1265
1266 static void __attribute__((__noreturn__))
1267 main_loop(void)
1268 {
1269 bool force_nl = false; /* when true, code must be broken */
1270 bool last_else = false; /* true iff last keyword was an else */
1271 int decl_ind = 0; /* current indentation for declarations */
1272 int di_stack[20]; /* a stack of structure indentation levels */
1273 bool tabs_to_var = false; /* true if using tabs to indent to var name */
1274 bool spaced_expr = false; /* whether we are in the expression of
1275 * if(...), while(...), etc. */
1276 stmt_head hd = hd_0; /* the type of statement for 'if (...)', 'for
1277 * (...)', etc */
1278 int quest_level = 0; /* when this is positive, we have seen a '?'
1279 * without the matching ':' in a '?:'
1280 * expression */
1281 bool seen_case = false; /* set to true when we see a 'case', so we
1282 * know what to do with the following colon */
1283
1284 di_stack[ps.decl_level = 0] = 0;
1285
1286 for (;;) { /* loop until we reach eof */
1287 lexer_symbol lsym = lexi();
1288
1289 search_stmt(&lsym, &force_nl, &last_else);
1290
1291 if (lsym == lsym_eof) {
1292 process_eof();
1293 /* NOTREACHED */
1294 }
1295
1296 if (lsym == lsym_newline || lsym == lsym_form_feed ||
1297 lsym == lsym_preprocessing)
1298 force_nl = false;
1299 else if (lsym != lsym_comment) {
1300 maybe_break_line(lsym, &force_nl);
1301 ps.in_stmt = true; /* add an extra level of indentation; turned
1302 * off again by a ';' or '}' */
1303 if (com.s != com.e)
1304 move_com_to_code();
1305 }
1306
1307 buf_reserve(&code, 3); /* space for 2 characters plus '\0' */
1308
1309 switch (lsym) {
1310
1311 case lsym_form_feed:
1312 process_form_feed();
1313 break;
1314
1315 case lsym_newline:
1316 process_newline();
1317 break;
1318
1319 case lsym_lparen_or_lbracket:
1320 process_lparen_or_lbracket(decl_ind, tabs_to_var, spaced_expr);
1321 break;
1322
1323 case lsym_rparen_or_rbracket:
1324 process_rparen_or_rbracket(&spaced_expr, &force_nl, hd);
1325 break;
1326
1327 case lsym_unary_op:
1328 process_unary_op(decl_ind, tabs_to_var);
1329 break;
1330
1331 case lsym_binary_op:
1332 process_binary_op();
1333 break;
1334
1335 case lsym_postfix_op:
1336 process_postfix_op();
1337 break;
1338
1339 case lsym_question:
1340 process_question(&quest_level);
1341 break;
1342
1343 case lsym_case_label:
1344 seen_case = true;
1345 goto copy_token;
1346
1347 case lsym_colon:
1348 process_colon(&quest_level, &force_nl, &seen_case);
1349 break;
1350
1351 case lsym_semicolon:
1352 process_semicolon(&seen_case, &quest_level, decl_ind, tabs_to_var,
1353 &spaced_expr, hd, &force_nl);
1354 break;
1355
1356 case lsym_lbrace:
1357 process_lbrace(&force_nl, &spaced_expr, hd, di_stack,
1358 (int)array_length(di_stack), &decl_ind);
1359 break;
1360
1361 case lsym_rbrace:
1362 process_rbrace(&spaced_expr, &decl_ind, di_stack);
1363 break;
1364
1365 case lsym_switch:
1366 spaced_expr = true; /* the interesting stuff is done after the
1367 * expressions are scanned */
1368 hd = hd_switch; /* remember the type of header for later use
1369 * by the parser */
1370 goto copy_token;
1371
1372 case lsym_for:
1373 spaced_expr = true;
1374 hd = hd_for;
1375 goto copy_token;
1376
1377 case lsym_if:
1378 spaced_expr = true;
1379 hd = hd_if;
1380 goto copy_token;
1381
1382 case lsym_while:
1383 spaced_expr = true;
1384 hd = hd_while;
1385 goto copy_token;
1386
1387 case lsym_do:
1388 process_do(&force_nl, &last_else);
1389 goto copy_token;
1390
1391 case lsym_else:
1392 process_else(&force_nl, &last_else);
1393 goto copy_token;
1394
1395 case lsym_typedef:
1396 case lsym_storage_class:
1397 blank_line_before = false;
1398 goto copy_token;
1399
1400 case lsym_tag:
1401 if (ps.p_l_follow > 0)
1402 goto copy_token;
1403 /* FALLTHROUGH */
1404 case lsym_type_outside_parentheses:
1405 process_type(&decl_ind, &tabs_to_var);
1406 goto copy_token;
1407
1408 case lsym_type_in_parentheses:
1409 case lsym_offsetof:
1410 case lsym_sizeof:
1411 case lsym_word:
1412 case lsym_funcname:
1413 case lsym_return:
1414 process_ident(lsym, decl_ind, tabs_to_var, &spaced_expr,
1415 &force_nl, hd);
1416 copy_token:
1417 copy_token();
1418 if (lsym != lsym_funcname)
1419 ps.want_blank = true;
1420 break;
1421
1422 case lsym_string_prefix:
1423 process_string_prefix();
1424 break;
1425
1426 case lsym_period:
1427 process_period();
1428 break;
1429
1430 case lsym_comma:
1431 process_comma(decl_ind, tabs_to_var, &force_nl);
1432 break;
1433
1434 case lsym_preprocessing:
1435 process_preprocessing();
1436 break;
1437
1438 case lsym_comment:
1439 process_comment();
1440 break;
1441
1442 default:
1443 break;
1444 }
1445
1446 *code.e = '\0';
1447 if (lsym != lsym_comment && lsym != lsym_newline &&
1448 lsym != lsym_preprocessing)
1449 ps.prev_token = lsym;
1450 }
1451 }
1452
1453 int
1454 main(int argc, char **argv)
1455 {
1456 main_init_globals();
1457 main_load_profiles(argc, argv);
1458 main_parse_command_line(argc, argv);
1459 #if HAVE_CAPSICUM
1460 init_capsicum();
1461 #endif
1462 main_prepare_parsing();
1463 main_loop();
1464 }
1465
1466 #ifdef debug
1467 void
1468 debug_printf(const char *fmt, ...)
1469 {
1470 FILE *f = output == stdout ? stderr : stdout;
1471 va_list ap;
1472
1473 va_start(ap, fmt);
1474 vfprintf(f, fmt, ap);
1475 va_end(ap);
1476 }
1477
1478 void
1479 debug_println(const char *fmt, ...)
1480 {
1481 FILE *f = output == stdout ? stderr : stdout;
1482 va_list ap;
1483
1484 va_start(ap, fmt);
1485 vfprintf(f, fmt, ap);
1486 va_end(ap);
1487 fprintf(f, "\n");
1488 }
1489
1490 void
1491 debug_vis_range(const char *prefix, const char *s, const char *e,
1492 const char *suffix)
1493 {
1494 debug_printf("%s", prefix);
1495 for (const char *p = s; p < e; p++) {
1496 if (*p == '\\' || *p == '"')
1497 debug_printf("\\%c", *p);
1498 else if (isprint((unsigned char)*p))
1499 debug_printf("%c", *p);
1500 else if (*p == '\n')
1501 debug_printf("\\n");
1502 else if (*p == '\t')
1503 debug_printf("\\t");
1504 else
1505 debug_printf("\\x%02x", (unsigned char)*p);
1506 }
1507 debug_printf("%s", suffix);
1508 }
1509 #endif
1510
1511 static void *
1512 nonnull(void *p)
1513 {
1514 if (p == NULL)
1515 err(EXIT_FAILURE, NULL);
1516 return p;
1517 }
1518
1519 void *
1520 xmalloc(size_t size)
1521 {
1522 return nonnull(malloc(size));
1523 }
1524
1525 void *
1526 xrealloc(void *p, size_t new_size)
1527 {
1528 return nonnull(realloc(p, new_size));
1529 }
1530
1531 char *
1532 xstrdup(const char *s)
1533 {
1534 return nonnull(strdup(s));
1535 }
1536