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