Sat Mar 13 12:52:24 2021 UTC ()
indent: split 'main_loop' into several functions

No functional change.


(rillig)
diff -r1.53 -r1.54 src/usr.bin/indent/indent.c

cvs diff -r1.53 -r1.54 src/usr.bin/indent/indent.c (expand / switch to unified diff)

--- src/usr.bin/indent/indent.c 2021/03/13 11:47:22 1.53
+++ src/usr.bin/indent/indent.c 2021/03/13 12:52:24 1.54
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: indent.c,v 1.53 2021/03/13 11:47:22 rillig Exp $ */ 1/* $NetBSD: indent.c,v 1.54 2021/03/13 12:52:24 rillig Exp $ */
2 2
3/*- 3/*-
4 * SPDX-License-Identifier: BSD-4-Clause 4 * SPDX-License-Identifier: BSD-4-Clause
5 * 5 *
6 * Copyright (c) 1985 Sun Microsystems, Inc. 6 * Copyright (c) 1985 Sun Microsystems, Inc.
7 * Copyright (c) 1976 Board of Trustees of the University of Illinois. 7 * Copyright (c) 1976 Board of Trustees of the University of Illinois.
8 * Copyright (c) 1980, 1993 8 * Copyright (c) 1980, 1993
9 * The Regents of the University of California. All rights reserved. 9 * The Regents of the University of California. All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -36,27 +36,27 @@ @@ -36,27 +36,27 @@
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE. 37 * SUCH DAMAGE.
38 */ 38 */
39 39
40#if 0 40#if 0
41#ifndef lint 41#ifndef lint
42static char sccsid[] = "@(#)indent.c 5.17 (Berkeley) 6/7/93"; 42static char sccsid[] = "@(#)indent.c 5.17 (Berkeley) 6/7/93";
43#endif /* not lint */ 43#endif /* not lint */
44#endif 44#endif
45 45
46#include <sys/cdefs.h> 46#include <sys/cdefs.h>
47#ifndef lint 47#ifndef lint
48#if defined(__NetBSD__) 48#if defined(__NetBSD__)
49__RCSID("$NetBSD: indent.c,v 1.53 2021/03/13 11:47:22 rillig Exp $"); 49__RCSID("$NetBSD: indent.c,v 1.54 2021/03/13 12:52:24 rillig Exp $");
50#elif defined(__FreeBSD__) 50#elif defined(__FreeBSD__)
51__FBSDID("$FreeBSD: head/usr.bin/indent/indent.c 340138 2018-11-04 19:24:49Z oshogbo $"); 51__FBSDID("$FreeBSD: head/usr.bin/indent/indent.c 340138 2018-11-04 19:24:49Z oshogbo $");
52#endif 52#endif
53#endif 53#endif
54 54
55#include <sys/param.h> 55#include <sys/param.h>
56#if HAVE_CAPSICUM 56#if HAVE_CAPSICUM
57#include <sys/capsicum.h> 57#include <sys/capsicum.h>
58#include <capsicum_helpers.h> 58#include <capsicum_helpers.h>
59#endif 59#endif
60#include <err.h> 60#include <err.h>
61#include <errno.h> 61#include <errno.h>
62#include <fcntl.h> 62#include <fcntl.h>
@@ -533,26 +533,739 @@ main_prepare_parsing(void) @@ -533,26 +533,739 @@ main_prepare_parsing(void)
533 if (*p == ' ') 533 if (*p == ' ')
534 col++; 534 col++;
535 else if (*p == '\t') 535 else if (*p == '\t')
536 col = opt.tabsize * (1 + (col - 1) / opt.tabsize) + 1; 536 col = opt.tabsize * (1 + (col - 1) / opt.tabsize) + 1;
537 else 537 else
538 break; 538 break;
539 p++; 539 p++;
540 } 540 }
541 if (col > opt.ind_size) 541 if (col > opt.ind_size)
542 ps.ind_level = ps.i_l_follow = col / opt.ind_size; 542 ps.ind_level = ps.i_l_follow = col / opt.ind_size;
543} 543}
544 544
545static void 545static void
 546process_end_of_file(void)
 547{
 548 if (s_lab != e_lab || s_code != e_code || s_com != e_com)
 549 dump_line();
 550
 551 if (ps.tos > 1) /* check for balanced braces */
 552 diag(1, "Stuff missing from end of file");
 553
 554 if (opt.verbose) {
 555 printf("There were %d output lines and %d comments\n",
 556 ps.out_lines, ps.out_coms);
 557 printf("(Lines with comments)/(Lines with code): %6.3f\n",
 558 (1.0 * ps.com_lines) / code_lines);
 559 }
 560
 561 fflush(output);
 562 exit(found_err);
 563}
 564
 565static void
 566process_comment_in_code(token_type type_code, int *inout_force_nl)
 567{
 568 if (*inout_force_nl &&
 569 type_code != semicolon &&
 570 (type_code != lbrace || !opt.btype_2)) {
 571
 572 /* we should force a broken line here */
 573 if (opt.verbose)
 574 diag(0, "Line broken");
 575 dump_line();
 576 ps.want_blank = false; /* dont insert blank at line start */
 577 *inout_force_nl = false;
 578 }
 579
 580 ps.in_stmt = true; /* turn on flag which causes an extra level of
 581 * indentation. this is turned off by a ; or
 582 * '}' */
 583 if (s_com != e_com) { /* the turkey has embedded a comment
 584 * in a line. fix it */
 585 int len = e_com - s_com;
 586
 587 check_size_code(len + 3);
 588 *e_code++ = ' ';
 589 memcpy(e_code, s_com, len);
 590 e_code += len;
 591 *e_code++ = ' ';
 592 *e_code = '\0'; /* null terminate code sect */
 593 ps.want_blank = false;
 594 e_com = s_com;
 595 }
 596}
 597
 598static void
 599process_form_feed(void)
 600{
 601 ps.use_ff = true; /* a form feed is treated much like a newline */
 602 dump_line();
 603 ps.want_blank = false;
 604}
 605
 606static void
 607process_newline(void)
 608{
 609 if (ps.last_token != comma || ps.p_l_follow > 0
 610 || !opt.leave_comma || ps.block_init || !break_comma || s_com != e_com) {
 611 dump_line();
 612 ps.want_blank = false;
 613 }
 614 ++line_no; /* keep track of input line number */
 615}
 616
 617static void
 618process_lparen_or_lbracket(int dec_ind, int tabs_to_var, int sp_sw)
 619{
 620 /* count parens to make Healy happy */
 621 if (++ps.p_l_follow == nitems(ps.paren_indents)) {
 622 diag(0, "Reached internal limit of %zu unclosed parens",
 623 nitems(ps.paren_indents));
 624 ps.p_l_follow--;
 625 }
 626 if (*token == '[')
 627 /* not a function pointer declaration or a function call */;
 628 else if (ps.in_decl && !ps.block_init && !ps.dumped_decl_indent &&
 629 ps.procname[0] == '\0' && ps.paren_level == 0) {
 630 /* function pointer declarations */
 631 indent_declaration(dec_ind, tabs_to_var);
 632 ps.dumped_decl_indent = true;
 633 } else if (ps.want_blank &&
 634 ((ps.last_token != ident && ps.last_token != funcname) ||
 635 opt.proc_calls_space ||
 636 (ps.keyword == rw_sizeof ? opt.Bill_Shannon :
 637 ps.keyword != rw_0 && ps.keyword != rw_offsetof)))
 638 *e_code++ = ' ';
 639 ps.want_blank = false;
 640 *e_code++ = token[0];
 641 ps.paren_indents[ps.p_l_follow - 1] =
 642 indentation_after_range(0, s_code, e_code);
 643 if (sp_sw && ps.p_l_follow == 1 && opt.extra_expression_indent
 644 && ps.paren_indents[0] < 2 * opt.ind_size)
 645 ps.paren_indents[0] = 2 * opt.ind_size;
 646 if (ps.in_or_st && *token == '(' && ps.tos <= 2) {
 647 /*
 648 * this is a kluge to make sure that declarations will be
 649 * aligned right if proc decl has an explicit type on it, i.e.
 650 * "int a(x) {..."
 651 */
 652 parse(semicolon); /* I said this was a kluge... */
 653 ps.in_or_st = false; /* turn off flag for structure decl or
 654 * initialization */
 655 }
 656 /* parenthesized type following sizeof or offsetof is not a cast */
 657 if (ps.keyword == rw_offsetof || ps.keyword == rw_sizeof)
 658 ps.not_cast_mask |= 1 << ps.p_l_follow;
 659}
 660
 661static void
 662process_rparen_or_rbracket(int *inout_sp_sw, int *inout_force_nl,
 663 token_type hd_type)
 664{
 665 if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.not_cast_mask) {
 666 ps.last_u_d = true;
 667 ps.cast_mask &= (1 << ps.p_l_follow) - 1;
 668 ps.want_blank = opt.space_after_cast;
 669 } else
 670 ps.want_blank = true;
 671 ps.not_cast_mask &= (1 << ps.p_l_follow) - 1;
 672
 673 if (--ps.p_l_follow < 0) {
 674 ps.p_l_follow = 0;
 675 diag(0, "Extra %c", *token);
 676 }
 677
 678 if (e_code == s_code) /* if the paren starts the line */
 679 ps.paren_level = ps.p_l_follow; /* then indent it */
 680
 681 *e_code++ = token[0];
 682
 683 if (*inout_sp_sw && (ps.p_l_follow == 0)) { /* check for end of if
 684 * (...), or some such */
 685 *inout_sp_sw = false;
 686 *inout_force_nl = true; /* must force newline after if */
 687 ps.last_u_d = true; /* inform lexi that a following
 688 * operator is unary */
 689 ps.in_stmt = false; /* dont use stmt continuation indentation */
 690
 691 parse(hd_type); /* let parser worry about if, or whatever */
 692 }
 693 ps.search_brace = opt.btype_2; /* this should ensure that constructs such
 694 * as main(){...} and int[]{...} have their
 695 * braces put in the right place */
 696}
 697
 698static void
 699process_unary_op(int dec_ind, int tabs_to_var)
 700{
 701 if (!ps.dumped_decl_indent && ps.in_decl && !ps.block_init &&
 702 ps.procname[0] == '\0' && ps.paren_level == 0) {
 703 /* pointer declarations */
 704
 705 /*
 706 * if this is a unary op in a declaration, we should indent
 707 * this token
 708 */
 709 int i;
 710 for (i = 0; token[i]; ++i)
 711 /* find length of token */;
 712 indent_declaration(dec_ind - i, tabs_to_var);
 713 ps.dumped_decl_indent = true;
 714 } else if (ps.want_blank)
 715 *e_code++ = ' ';
 716
 717 {
 718 int len = e_token - s_token;
 719
 720 check_size_code(len);
 721 memcpy(e_code, token, len);
 722 e_code += len;
 723 }
 724 ps.want_blank = false;
 725}
 726
 727static void
 728process_binary_op(void)
 729{
 730 int len = e_token - s_token;
 731
 732 check_size_code(len + 1);
 733 if (ps.want_blank)
 734 *e_code++ = ' ';
 735 memcpy(e_code, token, len);
 736 e_code += len;
 737
 738 ps.want_blank = true;
 739}
 740
 741static void
 742process_postfix_op(void)
 743{
 744 *e_code++ = token[0];
 745 *e_code++ = token[1];
 746 ps.want_blank = true;
 747}
 748
 749static void
 750process_question(int *inout_squest)
 751{
 752 (*inout_squest)++; /* this will be used when a later colon
 753 * appears so we can distinguish the
 754 * <c>?<n>:<n> construct */
 755 if (ps.want_blank)
 756 *e_code++ = ' ';
 757 *e_code++ = '?';
 758 ps.want_blank = true;
 759}
 760
 761static void
 762process_colon(int *inout_squest, int *inout_force_nl, int *inout_scase)
 763{
 764 if (*inout_squest > 0) { /* it is part of the <c>?<n>: <n> construct */
 765 --*inout_squest;
 766 if (ps.want_blank)
 767 *e_code++ = ' ';
 768 *e_code++ = ':';
 769 ps.want_blank = true;
 770 return;
 771 }
 772 if (ps.in_or_st) {
 773 *e_code++ = ':';
 774 ps.want_blank = false;
 775 return;
 776 }
 777 ps.in_stmt = false; /* seeing a label does not imply we are in a
 778 * stmt */
 779 /*
 780 * turn everything so far into a label
 781 */
 782 {
 783 int len = e_code - s_code;
 784
 785 check_size_label(len + 3);
 786 memcpy(e_lab, s_code, len);
 787 e_lab += len;
 788 *e_lab++ = ':';
 789 *e_lab = '\0';
 790 e_code = s_code;
 791 }
 792 *inout_force_nl = ps.pcase = *inout_scase; /* ps.pcase will be used by
 793 * dump_line to decide how to
 794 * indent the label. force_nl
 795 * will force a case n: to be
 796 * on a line by itself */
 797 *inout_scase = false;
 798 ps.want_blank = false;
 799}
 800
 801static void
 802process_semicolon(int *inout_scase, int *inout_squest, int const dec_ind,
 803 int const tabs_to_var, int *inout_sp_sw,
 804 token_type const hd_type,
 805 int *inout_force_nl)
 806{
 807 if (ps.dec_nest == 0)
 808 ps.in_or_st = false; /* we are not in an initialization or
 809 * structure declaration */
 810 *inout_scase = false; /* these will only need resetting in an error */
 811 *inout_squest = 0;
 812 if (ps.last_token == rparen)
 813 ps.in_parameter_declaration = 0;
 814 ps.cast_mask = 0;
 815 ps.not_cast_mask = 0;
 816 ps.block_init = 0;
 817 ps.block_init_level = 0;
 818 ps.just_saw_decl--;
 819
 820 if (ps.in_decl && s_code == e_code && !ps.block_init &&
 821 !ps.dumped_decl_indent && ps.paren_level == 0) {
 822 /* indent stray semicolons in declarations */
 823 indent_declaration(dec_ind - 1, tabs_to_var);
 824 ps.dumped_decl_indent = true;
 825 }
 826
 827 ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level
 828 * structure declaration, we
 829 * arent any more */
 830
 831 if ((!*inout_sp_sw || hd_type != for_exprs) && ps.p_l_follow > 0) {
 832
 833 /*
 834 * This should be true iff there were unbalanced parens in the
 835 * stmt. It is a bit complicated, because the semicolon might
 836 * be in a for stmt
 837 */
 838 diag(1, "Unbalanced parens");
 839 ps.p_l_follow = 0;
 840 if (*inout_sp_sw) { /* this is a check for an if, while, etc. with
 841 * unbalanced parens */
 842 *inout_sp_sw = false;
 843 parse(hd_type); /* dont lose the if, or whatever */
 844 }
 845 }
 846 *e_code++ = ';';
 847 ps.want_blank = true;
 848 ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the
 849 * middle of a stmt */
 850
 851 if (!*inout_sp_sw) { /* if not if for (;;) */
 852 parse(semicolon); /* let parser know about end of stmt */
 853 *inout_force_nl = true;/* force newline after an end of stmt */
 854 }
 855}
 856
 857static void
 858process_lbrace(int *inout_force_nl, int *inout_sp_sw, token_type hd_type,
 859 int *di_stack, int di_stack_cap, int *inout_dec_ind)
 860{
 861 ps.in_stmt = false; /* dont indent the {} */
 862 if (!ps.block_init)
 863 *inout_force_nl = true; /* force other stuff on same line as '{' onto
 864 * new line */
 865 else if (ps.block_init_level <= 0)
 866 ps.block_init_level = 1;
 867 else
 868 ps.block_init_level++;
 869
 870 if (s_code != e_code && !ps.block_init) {
 871 if (!opt.btype_2) {
 872 dump_line();
 873 ps.want_blank = false;
 874 } else if (ps.in_parameter_declaration && !ps.in_or_st) {
 875 ps.i_l_follow = 0;
 876 if (opt.function_brace_split) { /* dump the line prior
 877 * to the brace ... */
 878 dump_line();
 879 ps.want_blank = false;
 880 } else /* add a space between the decl and brace */
 881 ps.want_blank = true;
 882 }
 883 }
 884 if (ps.in_parameter_declaration)
 885 prefix_blankline_requested = 0;
 886
 887 if (ps.p_l_follow > 0) { /* check for preceding unbalanced
 888 * parens */
 889 diag(1, "Unbalanced parens");
 890 ps.p_l_follow = 0;
 891 if (*inout_sp_sw) { /* check for unclosed if, for, etc. */
 892 *inout_sp_sw = false;
 893 parse(hd_type);
 894 ps.ind_level = ps.i_l_follow;
 895 }
 896 }
 897 if (s_code == e_code)
 898 ps.ind_stmt = false; /* dont put extra indentation on line
 899 * with '{' */
 900 if (ps.in_decl && ps.in_or_st) { /* this is either a structure
 901 * declaration or an init */
 902 di_stack[ps.dec_nest] = *inout_dec_ind;
 903 if (++ps.dec_nest == di_stack_cap) {
 904 diag(0, "Reached internal limit of %d struct levels",
 905 di_stack_cap);
 906 ps.dec_nest--;
 907 }
 908 /* ? dec_ind = 0; */
 909 } else {
 910 ps.decl_on_line = false; /* we can't be in the middle of
 911 * a declaration, so don't do
 912 * special indentation of
 913 * comments */
 914 if (opt.blanklines_after_declarations_at_proctop
 915 && ps.in_parameter_declaration)
 916 postfix_blankline_requested = 1;
 917 ps.in_parameter_declaration = 0;
 918 ps.in_decl = false;
 919 }
 920 *inout_dec_ind = 0;
 921 parse(lbrace); /* let parser know about this */
 922 if (ps.want_blank) /* put a blank before '{' if '{' is not at
 923 * start of line */
 924 *e_code++ = ' ';
 925 ps.want_blank = false;
 926 *e_code++ = '{';
 927 ps.just_saw_decl = 0;
 928}
 929
 930static void
 931process_rbrace(int *inout_sp_sw, int *inout_dec_ind, const int *di_stack)
 932{
 933 if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be
 934 * omitted in declarations */
 935 parse(semicolon);
 936 if (ps.p_l_follow) { /* check for unclosed if, for, else. */
 937 diag(1, "Unbalanced parens");
 938 ps.p_l_follow = 0;
 939 *inout_sp_sw = false;
 940 }
 941 ps.just_saw_decl = 0;
 942 ps.block_init_level--;
 943 if (s_code != e_code && !ps.block_init) { /* '}' must be first on line */
 944 if (opt.verbose)
 945 diag(0, "Line broken");
 946 dump_line();
 947 }
 948 *e_code++ = '}';
 949 ps.want_blank = true;
 950 ps.in_stmt = ps.ind_stmt = false;
 951 if (ps.dec_nest > 0) { /* we are in multi-level structure declaration */
 952 *inout_dec_ind = di_stack[--ps.dec_nest];
 953 if (ps.dec_nest == 0 && !ps.in_parameter_declaration)
 954 ps.just_saw_decl = 2;
 955 ps.in_decl = true;
 956 }
 957 prefix_blankline_requested = 0;
 958 parse(rbrace); /* let parser know about this */
 959 ps.search_brace = opt.cuddle_else
 960 && ps.p_stack[ps.tos] == if_expr_stmt
 961 && ps.il[ps.tos] >= ps.ind_level;
 962 if (ps.tos <= 1 && opt.blanklines_after_procs && ps.dec_nest <= 0)
 963 postfix_blankline_requested = 1;
 964}
 965
 966static void
 967process_keyword_do_else(int *inout_force_nl, int *inout_last_else)
 968{
 969 ps.in_stmt = false;
 970 if (*token == 'e') {
 971 if (e_code != s_code && (!opt.cuddle_else || e_code[-1] != '}')) {
 972 if (opt.verbose)
 973 diag(0, "Line broken");
 974 dump_line(); /* make sure this starts a line */
 975 ps.want_blank = false;
 976 }
 977 *inout_force_nl = true;/* also, following stuff must go onto new line */
 978 *inout_last_else = 1;
 979 parse(keyword_else);
 980 } else {
 981 if (e_code != s_code) { /* make sure this starts a line */
 982 if (opt.verbose)
 983 diag(0, "Line broken");
 984 dump_line();
 985 ps.want_blank = false;
 986 }
 987 *inout_force_nl = true;/* also, following stuff must go onto new line */
 988 *inout_last_else = 0;
 989 parse(keyword_do);
 990 }
 991}
 992
 993static void
 994process_decl(int *out_dec_ind, int *out_tabs_to_var)
 995{
 996 parse(decl); /* let parser worry about indentation */
 997 if (ps.last_token == rparen && ps.tos <= 1) {
 998 if (s_code != e_code) {
 999 dump_line();
 1000 ps.want_blank = 0;
 1001 }
 1002 }
 1003 if (ps.in_parameter_declaration && opt.indent_parameters && ps.dec_nest == 0) {
 1004 ps.ind_level = ps.i_l_follow = 1;
 1005 ps.ind_stmt = 0;
 1006 }
 1007 ps.in_or_st = true; /* this might be a structure or initialization
 1008 * declaration */
 1009 ps.in_decl = ps.decl_on_line = ps.last_token != type_def;
 1010 if ( /* !ps.in_or_st && */ ps.dec_nest <= 0)
 1011 ps.just_saw_decl = 2;
 1012 prefix_blankline_requested = 0;
 1013 int i;
 1014 for (i = 0; token[i++];); /* get length of token */
 1015
 1016 if (ps.ind_level == 0 || ps.dec_nest > 0) {
 1017 /* global variable or struct member in local variable */
 1018 *out_dec_ind = opt.decl_indent > 0 ? opt.decl_indent : i;
 1019 *out_tabs_to_var = (opt.use_tabs ? opt.decl_indent > 0 : 0);
 1020 } else {
 1021 /* local variable */
 1022 *out_dec_ind = opt.local_decl_indent > 0 ? opt.local_decl_indent : i;
 1023 *out_tabs_to_var = (opt.use_tabs ? opt.local_decl_indent > 0 : 0);
 1024 }
 1025}
 1026
 1027static void
 1028process_ident(token_type type_code, int dec_ind, int tabs_to_var,
 1029 int *inout_sp_sw, int *inout_force_nl, token_type hd_type)
 1030{
 1031 if (ps.in_decl) {
 1032 if (type_code == funcname) {
 1033 ps.in_decl = false;
 1034 if (opt.procnames_start_line && s_code != e_code) {
 1035 *e_code = '\0';
 1036 dump_line();
 1037 } else if (ps.want_blank) {
 1038 *e_code++ = ' ';
 1039 }
 1040 ps.want_blank = false;
 1041 } else if (!ps.block_init && !ps.dumped_decl_indent &&
 1042 ps.paren_level == 0) { /* if we are in a declaration, we
 1043 * must indent identifier */
 1044 indent_declaration(dec_ind, tabs_to_var);
 1045 ps.dumped_decl_indent = true;
 1046 ps.want_blank = false;
 1047 }
 1048 } else if (*inout_sp_sw && ps.p_l_follow == 0) {
 1049 *inout_sp_sw = false;
 1050 *inout_force_nl = true;
 1051 ps.last_u_d = true;
 1052 ps.in_stmt = false;
 1053 parse(hd_type);
 1054 }
 1055}
 1056
 1057static void
 1058copy_id(void)
 1059{
 1060 int len = e_token - s_token;
 1061
 1062 check_size_code(len + 1);
 1063 if (ps.want_blank)
 1064 *e_code++ = ' ';
 1065 memcpy(e_code, s_token, len);
 1066 e_code += len;
 1067}
 1068
 1069static void
 1070process_string_prefix(void)
 1071{
 1072 int len = e_token - s_token;
 1073
 1074 check_size_code(len + 1);
 1075 if (ps.want_blank)
 1076 *e_code++ = ' ';
 1077 memcpy(e_code, token, len);
 1078 e_code += len;
 1079
 1080 ps.want_blank = false;
 1081}
 1082
 1083static void
 1084process_period(void)
 1085{
 1086 *e_code++ = '.'; /* move the period into line */
 1087 ps.want_blank = false; /* dont put a blank after a period */
 1088}
 1089
 1090static void
 1091process_comma(int dec_ind, int tabs_to_var, int *inout_force_nl)
 1092{
 1093 ps.want_blank = (s_code != e_code); /* only put blank after comma
 1094 * if comma does not start the line */
 1095 if (ps.in_decl && ps.procname[0] == '\0' && !ps.block_init &&
 1096 !ps.dumped_decl_indent && ps.paren_level == 0) {
 1097 /* indent leading commas and not the actual identifiers */
 1098 indent_declaration(dec_ind - 1, tabs_to_var);
 1099 ps.dumped_decl_indent = true;
 1100 }
 1101 *e_code++ = ',';
 1102 if (ps.p_l_follow == 0) {
 1103 if (ps.block_init_level <= 0)
 1104 ps.block_init = 0;
 1105 if (break_comma && (!opt.leave_comma ||
 1106 indentation_after_range(
 1107 compute_code_indent(), s_code, e_code)
 1108 >= opt.max_line_length - opt.tabsize))
 1109 *inout_force_nl = true;
 1110 }
 1111}
 1112
 1113static void
 1114process_preprocessing(void)
 1115{
 1116 if (s_com != e_com || s_lab != e_lab || s_code != e_code)
 1117 dump_line();
 1118 check_size_label(1);
 1119 *e_lab++ = '#'; /* move whole line to 'label' buffer */
 1120
 1121 {
 1122 int in_comment = 0;
 1123 int com_start = 0;
 1124 char quote = 0;
 1125 int com_end = 0;
 1126
 1127 while (*buf_ptr == ' ' || *buf_ptr == '\t') {
 1128 buf_ptr++;
 1129 if (buf_ptr >= buf_end)
 1130 fill_buffer();
 1131 }
 1132 while (*buf_ptr != '\n' || (in_comment && !had_eof)) {
 1133 check_size_label(2);
 1134 *e_lab = *buf_ptr++;
 1135 if (buf_ptr >= buf_end)
 1136 fill_buffer();
 1137 switch (*e_lab++) {
 1138 case '\\':
 1139 if (!in_comment) {
 1140 *e_lab++ = *buf_ptr++;
 1141 if (buf_ptr >= buf_end)
 1142 fill_buffer();
 1143 }
 1144 break;
 1145 case '/':
 1146 if (*buf_ptr == '*' && !in_comment && !quote) {
 1147 in_comment = 1;
 1148 *e_lab++ = *buf_ptr++;
 1149 com_start = e_lab - s_lab - 2;
 1150 }
 1151 break;
 1152 case '"':
 1153 if (quote == '"')
 1154 quote = 0;
 1155 break;
 1156 case '\'':
 1157 if (quote == '\'')
 1158 quote = 0;
 1159 break;
 1160 case '*':
 1161 if (*buf_ptr == '/' && in_comment) {
 1162 in_comment = 0;
 1163 *e_lab++ = *buf_ptr++;
 1164 com_end = e_lab - s_lab;
 1165 }
 1166 break;
 1167 }
 1168 }
 1169
 1170 while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
 1171 e_lab--;
 1172 if (e_lab - s_lab == com_end && bp_save == NULL) {
 1173 /* comment on preprocessor line */
 1174 if (sc_end == NULL) { /* if this is the first comment,
 1175 * we must set up the buffer */
 1176 save_com = sc_buf;
 1177 sc_end = &save_com[0];
 1178 } else {
 1179 *sc_end++ = '\n'; /* add newline between
 1180 * comments */
 1181 *sc_end++ = ' ';
 1182 --line_no;
 1183 }
 1184 if (sc_end - save_com + com_end - com_start > sc_size)
 1185 errx(1, "input too long");
 1186 memmove(sc_end, s_lab + com_start, com_end - com_start);
 1187 sc_end += com_end - com_start;
 1188 e_lab = s_lab + com_start;
 1189 while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
 1190 e_lab--;
 1191 bp_save = buf_ptr; /* save current input buffer */
 1192 be_save = buf_end;
 1193 buf_ptr = save_com; /* fix so that subsequent calls to
 1194 * lexi will take tokens out of
 1195 * save_com */
 1196 *sc_end++ = ' '; /* add trailing blank, just in case */
 1197 buf_end = sc_end;
 1198 sc_end = NULL;
 1199 }
 1200 check_size_label(1);
 1201 *e_lab = '\0'; /* null terminate line */
 1202 ps.pcase = false;
 1203 }
 1204
 1205 if (strncmp(s_lab, "#if", 3) == 0) { /* also ifdef, ifndef */
 1206 if ((size_t)ifdef_level < nitems(state_stack)) {
 1207 match_state[ifdef_level].tos = -1;
 1208 state_stack[ifdef_level++] = ps;
 1209 } else
 1210 diag(1, "#if stack overflow");
 1211 } else if (strncmp(s_lab, "#el", 3) == 0) { /* else, elif */
 1212 if (ifdef_level <= 0)
 1213 diag(1, s_lab[3] == 'i' ? "Unmatched #elif" : "Unmatched #else");
 1214 else {
 1215 match_state[ifdef_level - 1] = ps;
 1216 ps = state_stack[ifdef_level - 1];
 1217 }
 1218 } else if (strncmp(s_lab, "#endif", 6) == 0) {
 1219 if (ifdef_level <= 0)
 1220 diag(1, "Unmatched #endif");
 1221 else
 1222 ifdef_level--;
 1223 } else {
 1224 static const struct directives {
 1225 int size;
 1226 const char *string;
 1227 } recognized[] = {
 1228 {7, "include"},
 1229 {6, "define"},
 1230 {5, "undef"},
 1231 {4, "line"},
 1232 {5, "error"},
 1233 {6, "pragma"}
 1234 };
 1235 int d = nitems(recognized);
 1236 while (--d >= 0)
 1237 if (strncmp(s_lab + 1, recognized[d].string, recognized[d].size) == 0)
 1238 break;
 1239 if (d < 0) {
 1240 diag(1, "Unrecognized cpp directive");
 1241 return;
 1242 }
 1243 }
 1244 if (opt.blanklines_around_conditional_compilation) {
 1245 postfix_blankline_requested++;
 1246 n_real_blanklines = 0;
 1247 } else {
 1248 postfix_blankline_requested = 0;
 1249 prefix_blankline_requested = 0;
 1250 }
 1251
 1252 /*
 1253 * subsequent processing of the newline character will cause the line to
 1254 * be printed
 1255 */
 1256}
 1257
 1258static void
546main_loop(void) 1259main_loop(void)
547{ 1260{
548 token_type type_code; 1261 token_type type_code;
549 int force_nl; /* when true, code must be broken */ 1262 int force_nl; /* when true, code must be broken */
550 int last_else = false; /* true iff last keyword was an else */ 1263 int last_else = false; /* true iff last keyword was an else */
551 int dec_ind; /* current indentation for declarations */ 1264 int dec_ind; /* current indentation for declarations */
552 int di_stack[20]; /* a stack of structure indentation levels */ 1265 int di_stack[20]; /* a stack of structure indentation levels */
553 int tabs_to_var; /* true if using tabs to indent to var name */ 1266 int tabs_to_var; /* true if using tabs to indent to var name */
554 int sp_sw; /* when true, we are in the expression of 1267 int sp_sw; /* when true, we are in the expression of
555 * if(...), while(...), etc. */ 1268 * if(...), while(...), etc. */
556 token_type hd_type = end_of_file; /* used to store type of stmt 1269 token_type hd_type = end_of_file; /* used to store type of stmt
557 * for if (...), for (...), etc */ 1270 * for if (...), for (...), etc */
558 int squest; /* when this is positive, we have seen a ? 1271 int squest; /* when this is positive, we have seen a ?
@@ -574,738 +1287,165 @@ main_loop(void) @@ -574,738 +1287,165 @@ main_loop(void)
574 1287
575 type_code = lexi(&ps); /* lexi reads one token. The actual 1288 type_code = lexi(&ps); /* lexi reads one token. The actual
576 * characters read are stored in "token". lexi 1289 * characters read are stored in "token". lexi
577 * returns a code indicating the type of token */ 1290 * returns a code indicating the type of token */
578 1291
579 /* 1292 /*
580 * The following code moves newlines and comments following an if (), 1293 * The following code moves newlines and comments following an if (),
581 * while (), else, etc. up to the start of the following stmt to 1294 * while (), else, etc. up to the start of the following stmt to
582 * a buffer. This allows proper handling of both kinds of brace 1295 * a buffer. This allows proper handling of both kinds of brace
583 * placement (-br, -bl) and cuddling "else" (-ce). 1296 * placement (-br, -bl) and cuddling "else" (-ce).
584 */ 1297 */
585 search_brace(&type_code, &force_nl, &comment_buffered, &last_else); 1298 search_brace(&type_code, &force_nl, &comment_buffered, &last_else);
586 1299
587 if (type_code == end_of_file) { /* we got eof */ 1300 if (type_code == end_of_file) {
588 if (s_lab != e_lab || s_code != e_code 1301 process_end_of_file();
589 || s_com != e_com) /* must dump end of line */ 1302 return;
590 dump_line(); 
591 if (ps.tos > 1) /* check for balanced braces */ 
592 diag(1, "Stuff missing from end of file"); 
593 
594 if (opt.verbose) { 
595 printf("There were %d output lines and %d comments\n", 
596 ps.out_lines, ps.out_coms); 
597 printf("(Lines with comments)/(Lines with code): %6.3f\n", 
598 (1.0 * ps.com_lines) / code_lines); 
599 } 
600 fflush(output); 
601 exit(found_err); 
602 } 1303 }
 1304
603 if ( 1305 if (
604 type_code != comment && 1306 type_code != comment &&
605 type_code != newline && 1307 type_code != newline &&
606 type_code != preprocessing && 1308 type_code != preprocessing &&
607 type_code != form_feed) { 1309 type_code != form_feed) {
608 if (force_nl && 1310 process_comment_in_code(type_code, &force_nl);
609 type_code != semicolon && 
610 (type_code != lbrace || !opt.btype_2)) { 
611 /* we should force a broken line here */ 
612 if (opt.verbose) 
613 diag(0, "Line broken"); 
614 dump_line(); 
615 ps.want_blank = false; /* dont insert blank at line start */ 
616 force_nl = false; 
617 } 
618 ps.in_stmt = true; /* turn on flag which causes an extra level of 
619 * indentation. this is turned off by a ; or 
620 * '}' */ 
621 if (s_com != e_com) { /* the turkey has embedded a comment 
622 * in a line. fix it */ 
623 int len = e_com - s_com; 
624 1311
625 check_size_code(len + 3); 
626 *e_code++ = ' '; 
627 memcpy(e_code, s_com, len); 
628 e_code += len; 
629 *e_code++ = ' '; 
630 *e_code = '\0'; /* null terminate code sect */ 
631 ps.want_blank = false; 
632 e_com = s_com; 
633 } 
634 } else if (type_code != comment) /* preserve force_nl thru a comment */ 1312 } else if (type_code != comment) /* preserve force_nl thru a comment */
635 force_nl = false; /* cancel forced newline after newline, form 1313 force_nl = false; /* cancel forced newline after newline, form
636 * feed, etc */ 1314 * feed, etc */
637 1315
638 1316
639 1317
640 /*-----------------------------------------------------*\ 1318 /*-----------------------------------------------------*\
641 | do switch on type of token scanned | 1319 | do switch on type of token scanned |
642 \*-----------------------------------------------------*/ 1320 \*-----------------------------------------------------*/
643 check_size_code(3); /* maximum number of increments of e_code 1321 check_size_code(3); /* maximum number of increments of e_code
644 * before the next check_size_code or 1322 * before the next check_size_code or
645 * dump_line() is 2. After that there's the 1323 * dump_line() is 2. After that there's the
646 * final increment for the null character. */ 1324 * final increment for the null character. */
647 switch (type_code) { /* now, decide what to do with the token */ 1325 switch (type_code) { /* now, decide what to do with the token */
648 1326
649 case form_feed: /* found a form feed in line */ 1327 case form_feed: /* found a form feed in line */
650 ps.use_ff = true; /* a form feed is treated much like a newline */ 1328 process_form_feed();
651 dump_line(); 
652 ps.want_blank = false; 
653 break; 1329 break;
654 1330
655 case newline: 1331 case newline:
656 if (ps.last_token != comma || ps.p_l_follow > 0 1332 process_newline();
657 || !opt.leave_comma || ps.block_init || !break_comma || s_com != e_com) { 
658 dump_line(); 
659 ps.want_blank = false; 
660 } 
661 ++line_no; /* keep track of input line number */ 
662 break; 1333 break;
663 1334
664 case lparen: /* got a '(' or '[' */ 1335 case lparen: /* got a '(' or '[' */
665 /* count parens to make Healy happy */ 1336 process_lparen_or_lbracket(dec_ind, tabs_to_var, sp_sw);
666 if (++ps.p_l_follow == nitems(ps.paren_indents)) { 
667 diag(0, "Reached internal limit of %zu unclosed parens", 
668 nitems(ps.paren_indents)); 
669 ps.p_l_follow--; 
670 } 
671 if (*token == '[') 
672 /* not a function pointer declaration or a function call */; 
673 else if (ps.in_decl && !ps.block_init && !ps.dumped_decl_indent && 
674 ps.procname[0] == '\0' && ps.paren_level == 0) { 
675 /* function pointer declarations */ 
676 indent_declaration(dec_ind, tabs_to_var); 
677 ps.dumped_decl_indent = true; 
678 } else if (ps.want_blank && 
679 ((ps.last_token != ident && ps.last_token != funcname) || 
680 opt.proc_calls_space || 
681 (ps.keyword == rw_sizeof ? opt.Bill_Shannon : 
682 ps.keyword != rw_0 && ps.keyword != rw_offsetof))) 
683 *e_code++ = ' '; 
684 ps.want_blank = false; 
685 *e_code++ = token[0]; 
686 ps.paren_indents[ps.p_l_follow - 1] = 
687 indentation_after_range(0, s_code, e_code); 
688 if (sp_sw && ps.p_l_follow == 1 && opt.extra_expression_indent 
689 && ps.paren_indents[0] < 2 * opt.ind_size) 
690 ps.paren_indents[0] = 2 * opt.ind_size; 
691 if (ps.in_or_st && *token == '(' && ps.tos <= 2) { 
692 /* 
693 * this is a kluge to make sure that declarations will be 
694 * aligned right if proc decl has an explicit type on it, i.e. 
695 * "int a(x) {..." 
696 */ 
697 parse(semicolon); /* I said this was a kluge... */ 
698 ps.in_or_st = false; /* turn off flag for structure decl or 
699 * initialization */ 
700 } 
701 /* parenthesized type following sizeof or offsetof is not a cast */ 
702 if (ps.keyword == rw_offsetof || ps.keyword == rw_sizeof) 
703 ps.not_cast_mask |= 1 << ps.p_l_follow; 
704 break; 1337 break;
705 1338
706 case rparen: /* got a ')' or ']' */ 1339 case rparen: /* got a ')' or ']' */
707 if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.not_cast_mask) { 1340 process_rparen_or_rbracket(&sp_sw, &force_nl, hd_type);
708 ps.last_u_d = true; 
709 ps.cast_mask &= (1 << ps.p_l_follow) - 1; 
710 ps.want_blank = opt.space_after_cast; 
711 } else 
712 ps.want_blank = true; 
713 ps.not_cast_mask &= (1 << ps.p_l_follow) - 1; 
714 if (--ps.p_l_follow < 0) { 
715 ps.p_l_follow = 0; 
716 diag(0, "Extra %c", *token); 
717 } 
718 if (e_code == s_code) /* if the paren starts the line */ 
719 ps.paren_level = ps.p_l_follow; /* then indent it */ 
720 
721 *e_code++ = token[0]; 
722 
723 if (sp_sw && (ps.p_l_follow == 0)) { /* check for end of if 
724 * (...), or some such */ 
725 sp_sw = false; 
726 force_nl = true; /* must force newline after if */ 
727 ps.last_u_d = true; /* inform lexi that a following 
728 * operator is unary */ 
729 ps.in_stmt = false; /* dont use stmt continuation 
730 * indentation */ 
731 
732 parse(hd_type); /* let parser worry about if, or whatever */ 
733 } 
734 ps.search_brace = opt.btype_2; /* this should ensure that 
735 * constructs such as main(){...} 
736 * and int[]{...} have their braces 
737 * put in the right place */ 
738 break; 1341 break;
739 1342
740 case unary_op: /* this could be any unary operation */ 1343 case unary_op: /* this could be any unary operation */
741 if (!ps.dumped_decl_indent && ps.in_decl && !ps.block_init && 1344 process_unary_op(dec_ind, tabs_to_var);
742 ps.procname[0] == '\0' && ps.paren_level == 0) { 
743 /* pointer declarations */ 
744 
745 /* 
746 * if this is a unary op in a declaration, we should indent 
747 * this token 
748 */ 
749 int i; 
750 for (i = 0; token[i]; ++i) 
751 /* find length of token */; 
752 indent_declaration(dec_ind - i, tabs_to_var); 
753 ps.dumped_decl_indent = true; 
754 } else if (ps.want_blank) 
755 *e_code++ = ' '; 
756 
757 { 
758 int len = e_token - s_token; 
759 
760 check_size_code(len); 
761 memcpy(e_code, token, len); 
762 e_code += len; 
763 } 
764 ps.want_blank = false; 
765 break; 1345 break;
766 1346
767 case binary_op: /* any binary operation */ 1347 case binary_op: /* any binary operation */
768 { 1348 process_binary_op();
769 int len = e_token - s_token; 
770 
771 check_size_code(len + 1); 
772 if (ps.want_blank) 
773 *e_code++ = ' '; 
774 memcpy(e_code, token, len); 
775 e_code += len; 
776 } 
777 ps.want_blank = true; 
778 break; 1349 break;
779 1350
780 case postfix_op: /* got a trailing ++ or -- */ 1351 case postfix_op: /* got a trailing ++ or -- */
781 *e_code++ = token[0]; 1352 process_postfix_op();
782 *e_code++ = token[1]; 
783 ps.want_blank = true; 
784 break; 1353 break;
785 1354
786 case question: /* got a ? */ 1355 case question: /* got a ? */
787 squest++; /* this will be used when a later colon 1356 process_question(&squest);
788 * appears so we can distinguish the 
789 * <c>?<n>:<n> construct */ 
790 if (ps.want_blank) 
791 *e_code++ = ' '; 
792 *e_code++ = '?'; 
793 ps.want_blank = true; 
794 break; 1357 break;
795 1358
796 case case_label: /* got word 'case' or 'default' */ 1359 case case_label: /* got word 'case' or 'default' */
797 scase = true; /* so we can process the later colon properly */ 1360 scase = true; /* so we can process the later colon properly */
798 goto copy_id; 1361 goto copy_id;
799 1362
800 case colon: /* got a ':' */ 1363 case colon: /* got a ':' */
801 if (squest > 0) { /* it is part of the <c>?<n>: <n> construct */ 1364 process_colon(&squest, &force_nl, &scase);
802 --squest; 
803 if (ps.want_blank) 
804 *e_code++ = ' '; 
805 *e_code++ = ':'; 
806 ps.want_blank = true; 
807 break; 
808 } 
809 if (ps.in_or_st) { 
810 *e_code++ = ':'; 
811 ps.want_blank = false; 
812 break; 
813 } 
814 ps.in_stmt = false; /* seeing a label does not imply we are in a 
815 * stmt */ 
816 /* 
817 * turn everything so far into a label 
818 */ 
819 { 
820 int len = e_code - s_code; 
821 
822 check_size_label(len + 3); 
823 memcpy(e_lab, s_code, len); 
824 e_lab += len; 
825 *e_lab++ = ':'; 
826 *e_lab = '\0'; 
827 e_code = s_code; 
828 } 
829 force_nl = ps.pcase = scase; /* ps.pcase will be used by 
830 * dump_line to decide how to 
831 * indent the label. force_nl 
832 * will force a case n: to be 
833 * on a line by itself */ 
834 scase = false; 
835 ps.want_blank = false; 
836 break; 1365 break;
837 1366
838 case semicolon: /* got a ';' */ 1367 case semicolon: /* got a ';' */
839 if (ps.dec_nest == 0) 1368 process_semicolon(&scase, &squest, dec_ind, tabs_to_var, &sp_sw,
840 ps.in_or_st = false; /* we are not in an initialization or 1369 hd_type, &force_nl);
841 * structure declaration */ 
842 scase = false; /* these will only need resetting in an error */ 
843 squest = 0; 
844 if (ps.last_token == rparen) 
845 ps.in_parameter_declaration = 0; 
846 ps.cast_mask = 0; 
847 ps.not_cast_mask = 0; 
848 ps.block_init = 0; 
849 ps.block_init_level = 0; 
850 ps.just_saw_decl--; 
851 
852 if (ps.in_decl && s_code == e_code && !ps.block_init && 
853 !ps.dumped_decl_indent && ps.paren_level == 0) { 
854 /* indent stray semicolons in declarations */ 
855 indent_declaration(dec_ind - 1, tabs_to_var); 
856 ps.dumped_decl_indent = true; 
857 } 
858 
859 ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level 
860 * structure declaration, we 
861 * arent any more */ 
862 
863 if ((!sp_sw || hd_type != for_exprs) && ps.p_l_follow > 0) { 
864 
865 /* 
866 * This should be true iff there were unbalanced parens in the 
867 * stmt. It is a bit complicated, because the semicolon might 
868 * be in a for stmt 
869 */ 
870 diag(1, "Unbalanced parens"); 
871 ps.p_l_follow = 0; 
872 if (sp_sw) { /* this is a check for an if, while, etc. with 
873 * unbalanced parens */ 
874 sp_sw = false; 
875 parse(hd_type); /* dont lose the if, or whatever */ 
876 } 
877 } 
878 *e_code++ = ';'; 
879 ps.want_blank = true; 
880 ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the 
881 * middle of a stmt */ 
882 
883 if (!sp_sw) { /* if not if for (;;) */ 
884 parse(semicolon); /* let parser know about end of stmt */ 
885 force_nl = true;/* force newline after an end of stmt */ 
886 } 
887 break; 1370 break;
888 1371
889 case lbrace: /* got a '{' */ 1372 case lbrace: /* got a '{' */
890 ps.in_stmt = false; /* dont indent the {} */ 1373 process_lbrace(&force_nl, &sp_sw, hd_type, di_stack,
891 if (!ps.block_init) 1374 nitems(di_stack), &dec_ind);
892 force_nl = true;/* force other stuff on same line as '{' onto 
893 * new line */ 
894 else if (ps.block_init_level <= 0) 
895 ps.block_init_level = 1; 
896 else 
897 ps.block_init_level++; 
898 
899 if (s_code != e_code && !ps.block_init) { 
900 if (!opt.btype_2) { 
901 dump_line(); 
902 ps.want_blank = false; 
903 } else if (ps.in_parameter_declaration && !ps.in_or_st) { 
904 ps.i_l_follow = 0; 
905 if (opt.function_brace_split) { /* dump the line prior 
906 * to the brace ... */ 
907 dump_line(); 
908 ps.want_blank = false; 
909 } else /* add a space between the decl and brace */ 
910 ps.want_blank = true; 
911 } 
912 } 
913 if (ps.in_parameter_declaration) 
914 prefix_blankline_requested = 0; 
915 
916 if (ps.p_l_follow > 0) { /* check for preceding unbalanced 
917 * parens */ 
918 diag(1, "Unbalanced parens"); 
919 ps.p_l_follow = 0; 
920 if (sp_sw) { /* check for unclosed if, for, etc. */ 
921 sp_sw = false; 
922 parse(hd_type); 
923 ps.ind_level = ps.i_l_follow; 
924 } 
925 } 
926 if (s_code == e_code) 
927 ps.ind_stmt = false; /* dont put extra indentation on line 
928 * with '{' */ 
929 if (ps.in_decl && ps.in_or_st) { /* this is either a structure 
930 * declaration or an init */ 
931 di_stack[ps.dec_nest] = dec_ind; 
932 if (++ps.dec_nest == nitems(di_stack)) { 
933 diag(0, "Reached internal limit of %zu struct levels", 
934 nitems(di_stack)); 
935 ps.dec_nest--; 
936 } 
937 /* ? dec_ind = 0; */ 
938 } else { 
939 ps.decl_on_line = false; /* we can't be in the middle of 
940 * a declaration, so don't do 
941 * special indentation of 
942 * comments */ 
943 if (opt.blanklines_after_declarations_at_proctop 
944 && ps.in_parameter_declaration) 
945 postfix_blankline_requested = 1; 
946 ps.in_parameter_declaration = 0; 
947 ps.in_decl = false; 
948 } 
949 dec_ind = 0; 
950 parse(lbrace); /* let parser know about this */ 
951 if (ps.want_blank) /* put a blank before '{' if '{' is not at 
952 * start of line */ 
953 *e_code++ = ' '; 
954 ps.want_blank = false; 
955 *e_code++ = '{'; 
956 ps.just_saw_decl = 0; 
957 break; 1375 break;
958 1376
959 case rbrace: /* got a '}' */ 1377 case rbrace: /* got a '}' */
960 if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be 1378 process_rbrace(&sp_sw, &dec_ind, di_stack);
961 * omitted in 
962 * declarations */ 
963 parse(semicolon); 
964 if (ps.p_l_follow) {/* check for unclosed if, for, else. */ 
965 diag(1, "Unbalanced parens"); 
966 ps.p_l_follow = 0; 
967 sp_sw = false; 
968 } 
969 ps.just_saw_decl = 0; 
970 ps.block_init_level--; 
971 if (s_code != e_code && !ps.block_init) { /* '}' must be first on 
972 * line */ 
973 if (opt.verbose) 
974 diag(0, "Line broken"); 
975 dump_line(); 
976 } 
977 *e_code++ = '}'; 
978 ps.want_blank = true; 
979 ps.in_stmt = ps.ind_stmt = false; 
980 if (ps.dec_nest > 0) { /* we are in multi-level structure 
981 * declaration */ 
982 dec_ind = di_stack[--ps.dec_nest]; 
983 if (ps.dec_nest == 0 && !ps.in_parameter_declaration) 
984 ps.just_saw_decl = 2; 
985 ps.in_decl = true; 
986 } 
987 prefix_blankline_requested = 0; 
988 parse(rbrace); /* let parser know about this */ 
989 ps.search_brace = opt.cuddle_else 
990 && ps.p_stack[ps.tos] == if_expr_stmt 
991 && ps.il[ps.tos] >= ps.ind_level; 
992 if (ps.tos <= 1 && opt.blanklines_after_procs && ps.dec_nest <= 0) 
993 postfix_blankline_requested = 1; 
994 break; 1379 break;
995 1380
996 case switch_expr: /* got keyword "switch" */ 1381 case switch_expr: /* got keyword "switch" */
997 sp_sw = true; 1382 sp_sw = true;
998 hd_type = switch_expr; /* keep this for when we have seen the 1383 hd_type = switch_expr; /* keep this for when we have seen the
999 * expression */ 1384 * expression */
1000 goto copy_id; /* go move the token into buffer */ 1385 goto copy_id; /* go move the token into buffer */
1001 1386
1002 case keyword_for_if_while: 1387 case keyword_for_if_while:
1003 sp_sw = true; /* the interesting stuff is done after the 1388 sp_sw = true; /* the interesting stuff is done after the
1004 * expression is scanned */ 1389 * expression is scanned */
1005 hd_type = (*token == 'i' ? if_expr : 1390 hd_type = (*token == 'i' ? if_expr :
1006 (*token == 'w' ? while_expr : for_exprs)); 1391 (*token == 'w' ? while_expr : for_exprs));
1007 1392
1008 /* 1393 /* remember the type of header for later use by parser */
1009 * remember the type of header for later use by parser 
1010 */ 
1011 goto copy_id; /* copy the token into line */ 1394 goto copy_id; /* copy the token into line */
1012 1395
1013 case keyword_do_else: 1396 case keyword_do_else:
1014 ps.in_stmt = false; 1397 process_keyword_do_else(&force_nl, &last_else);
1015 if (*token == 'e') { 
1016 if (e_code != s_code && (!opt.cuddle_else || e_code[-1] != '}')) { 
1017 if (opt.verbose) 
1018 diag(0, "Line broken"); 
1019 dump_line();/* make sure this starts a line */ 
1020 ps.want_blank = false; 
1021 } 
1022 force_nl = true;/* also, following stuff must go onto new line */ 
1023 last_else = 1; 
1024 parse(keyword_else); 
1025 } else { 
1026 if (e_code != s_code) { /* make sure this starts a line */ 
1027 if (opt.verbose) 
1028 diag(0, "Line broken"); 
1029 dump_line(); 
1030 ps.want_blank = false; 
1031 } 
1032 force_nl = true;/* also, following stuff must go onto new line */ 
1033 last_else = 0; 
1034 parse(keyword_do); 
1035 } 
1036 goto copy_id; /* move the token into line */ 1398 goto copy_id; /* move the token into line */
1037 1399
1038 case type_def: 1400 case type_def:
1039 case storage_class: 1401 case storage_class:
1040 prefix_blankline_requested = 0; 1402 prefix_blankline_requested = 0;
1041 goto copy_id; 1403 goto copy_id;
1042 1404
1043 case keyword_struct_union_enum: 1405 case keyword_struct_union_enum:
1044 if (ps.p_l_follow > 0) 1406 if (ps.p_l_follow > 0)
1045 goto copy_id; 1407 goto copy_id;
1046 /* FALLTHROUGH */ 1408 /* FALLTHROUGH */
1047 case decl: /* we have a declaration type (int, etc.) */ 1409 case decl: /* we have a declaration type (int, etc.) */
1048 parse(decl); /* let parser worry about indentation */ 1410 process_decl(&dec_ind, &tabs_to_var);
1049 if (ps.last_token == rparen && ps.tos <= 1) { 
1050 if (s_code != e_code) { 
1051 dump_line(); 
1052 ps.want_blank = 0; 
1053 } 
1054 } 
1055 if (ps.in_parameter_declaration && opt.indent_parameters && ps.dec_nest == 0) { 
1056 ps.ind_level = ps.i_l_follow = 1; 
1057 ps.ind_stmt = 0; 
1058 } 
1059 ps.in_or_st = true; /* this might be a structure or initialization 
1060 * declaration */ 
1061 ps.in_decl = ps.decl_on_line = ps.last_token != type_def; 
1062 if ( /* !ps.in_or_st && */ ps.dec_nest <= 0) 
1063 ps.just_saw_decl = 2; 
1064 prefix_blankline_requested = 0; 
1065 int i; 
1066 for (i = 0; token[i++];); /* get length of token */ 
1067 
1068 if (ps.ind_level == 0 || ps.dec_nest > 0) { 
1069 /* global variable or struct member in local variable */ 
1070 dec_ind = opt.decl_indent > 0 ? opt.decl_indent : i; 
1071 tabs_to_var = (opt.use_tabs ? opt.decl_indent > 0 : 0); 
1072 } else { 
1073 /* local variable */ 
1074 dec_ind = opt.local_decl_indent > 0 ? opt.local_decl_indent : i; 
1075 tabs_to_var = (opt.use_tabs ? opt.local_decl_indent > 0 : 0); 
1076 } 
1077 goto copy_id; 1411 goto copy_id;
1078 1412
1079 case funcname: 1413 case funcname:
1080 case ident: /* got an identifier or constant */ 1414 case ident: /* got an identifier or constant */
1081 if (ps.in_decl) { 1415 process_ident(type_code, dec_ind, tabs_to_var, &sp_sw, &force_nl,
1082 if (type_code == funcname) { 1416 hd_type);
1083 ps.in_decl = false; 
1084 if (opt.procnames_start_line && s_code != e_code) { 
1085 *e_code = '\0'; 
1086 dump_line(); 
1087 } else if (ps.want_blank) { 
1088 *e_code++ = ' '; 
1089 } 
1090 ps.want_blank = false; 
1091 } else if (!ps.block_init && !ps.dumped_decl_indent && 
1092 ps.paren_level == 0) { /* if we are in a declaration, we 
1093 * must indent identifier */ 
1094 indent_declaration(dec_ind, tabs_to_var); 
1095 ps.dumped_decl_indent = true; 
1096 ps.want_blank = false; 
1097 } 
1098 } else if (sp_sw && ps.p_l_follow == 0) { 
1099 sp_sw = false; 
1100 force_nl = true; 
1101 ps.last_u_d = true; 
1102 ps.in_stmt = false; 
1103 parse(hd_type); 
1104 } 
1105 copy_id: 1417 copy_id:
1106 { 1418 copy_id();
1107 int len = e_token - s_token; 
1108 
1109 check_size_code(len + 1); 
1110 if (ps.want_blank) 
1111 *e_code++ = ' '; 
1112 memcpy(e_code, s_token, len); 
1113 e_code += len; 
1114 } 
1115 if (type_code != funcname) 1419 if (type_code != funcname)
1116 ps.want_blank = true; 1420 ps.want_blank = true;
1117 break; 1421 break;
1118 1422
1119 case string_prefix: 1423 case string_prefix:
1120 { 1424 process_string_prefix();
1121 int len = e_token - s_token; 
1122 
1123 check_size_code(len + 1); 
1124 if (ps.want_blank) 
1125 *e_code++ = ' '; 
1126 memcpy(e_code, token, len); 
1127 e_code += len; 
1128 } 
1129 ps.want_blank = false; 
1130 break; 1425 break;
1131 1426
1132 case period: /* treat a period kind of like a binary 1427 case period:
1133 * operation */ 1428 process_period();
1134 *e_code++ = '.'; /* move the period into line */ 
1135 ps.want_blank = false; /* dont put a blank after a period */ 
1136 break; 1429 break;
1137 1430
1138 case comma: 1431 case comma:
1139 ps.want_blank = (s_code != e_code); /* only put blank after comma 1432 process_comma(dec_ind, tabs_to_var, &force_nl);
1140 * if comma does not start the 
1141 * line */ 
1142 if (ps.in_decl && ps.procname[0] == '\0' && !ps.block_init && 
1143 !ps.dumped_decl_indent && ps.paren_level == 0) { 
1144 /* indent leading commas and not the actual identifiers */ 
1145 indent_declaration(dec_ind - 1, tabs_to_var); 
1146 ps.dumped_decl_indent = true; 
1147 } 
1148 *e_code++ = ','; 
1149 if (ps.p_l_follow == 0) { 
1150 if (ps.block_init_level <= 0) 
1151 ps.block_init = 0; 
1152 if (break_comma && (!opt.leave_comma || 
1153 indentation_after_range( 
1154 compute_code_indent(), s_code, e_code) 
1155 >= opt.max_line_length - opt.tabsize)) 
1156 force_nl = true; 
1157 } 
1158 break; 1433 break;
1159 1434
1160 case preprocessing: /* '#' */ 1435 case preprocessing: /* '#' */
1161 if (s_com != e_com || s_lab != e_lab || s_code != e_code) 1436 process_preprocessing();
1162 dump_line(); 1437 break;
1163 check_size_label(1); 1438 case comment: /* we have gotten a '/' followed by '*' */
1164 *e_lab++ = '#'; /* move whole line to 'label' buffer */ 
1165 { 
1166 int in_comment = 0; 
1167 int com_start = 0; 
1168 char quote = 0; 
1169 int com_end = 0; 
1170 
1171 while (*buf_ptr == ' ' || *buf_ptr == '\t') { 
1172 buf_ptr++; 
1173 if (buf_ptr >= buf_end) 
1174 fill_buffer(); 
1175 } 
1176 while (*buf_ptr != '\n' || (in_comment && !had_eof)) { 
1177 check_size_label(2); 
1178 *e_lab = *buf_ptr++; 
1179 if (buf_ptr >= buf_end) 
1180 fill_buffer(); 
1181 switch (*e_lab++) { 
1182 case '\\': 
1183 if (!in_comment) { 
1184 *e_lab++ = *buf_ptr++; 
1185 if (buf_ptr >= buf_end) 
1186 fill_buffer(); 
1187 } 
1188 break; 
1189 case '/': 
1190 if (*buf_ptr == '*' && !in_comment && !quote) { 
1191 in_comment = 1; 
1192 *e_lab++ = *buf_ptr++; 
1193 com_start = e_lab - s_lab - 2; 
1194 } 
1195 break; 
1196 case '"': 
1197 if (quote == '"') 
1198 quote = 0; 
1199 break; 
1200 case '\'': 
1201 if (quote == '\'') 
1202 quote = 0; 
1203 break; 
1204 case '*': 
1205 if (*buf_ptr == '/' && in_comment) { 
1206 in_comment = 0; 
1207 *e_lab++ = *buf_ptr++; 
1208 com_end = e_lab - s_lab; 
1209 } 
1210 break; 
1211 } 
1212 } 
1213 
1214 while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 
1215 e_lab--; 
1216 if (e_lab - s_lab == com_end && bp_save == NULL) { 
1217 /* comment on preprocessor line */ 
1218 if (sc_end == NULL) { /* if this is the first comment, 
1219 * we must set up the buffer */ 
1220 save_com = sc_buf; 
1221 sc_end = &save_com[0]; 
1222 } else { 
1223 *sc_end++ = '\n'; /* add newline between 
1224 * comments */ 
1225 *sc_end++ = ' '; 
1226 --line_no; 
1227 } 
1228 if (sc_end - save_com + com_end - com_start > sc_size) 
1229 errx(1, "input too long"); 
1230 memmove(sc_end, s_lab + com_start, com_end - com_start); 
1231 sc_end += com_end - com_start; 
1232 e_lab = s_lab + com_start; 
1233 while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 
1234 e_lab--; 
1235 bp_save = buf_ptr; /* save current input buffer */ 
1236 be_save = buf_end; 
1237 buf_ptr = save_com; /* fix so that subsequent calls to 
1238 * lexi will take tokens out of 
1239 * save_com */ 
1240 *sc_end++ = ' '; /* add trailing blank, just in case */ 
1241 buf_end = sc_end; 
1242 sc_end = NULL; 
1243 } 
1244 check_size_label(1); 
1245 *e_lab = '\0'; /* null terminate line */ 
1246 ps.pcase = false; 
1247 } 
1248 
1249 if (strncmp(s_lab, "#if", 3) == 0) { /* also ifdef, ifndef */ 
1250 if ((size_t)ifdef_level < nitems(state_stack)) { 
1251 match_state[ifdef_level].tos = -1; 
1252 state_stack[ifdef_level++] = ps; 
1253 } else 
1254 diag(1, "#if stack overflow"); 
1255 } else if (strncmp(s_lab, "#el", 3) == 0) { /* else, elif */ 
1256 if (ifdef_level <= 0) 
1257 diag(1, s_lab[3] == 'i' ? "Unmatched #elif" : "Unmatched #else"); 
1258 else { 
1259 match_state[ifdef_level - 1] = ps; 
1260 ps = state_stack[ifdef_level - 1]; 
1261 } 
1262 } else if (strncmp(s_lab, "#endif", 6) == 0) { 
1263 if (ifdef_level <= 0) 
1264 diag(1, "Unmatched #endif"); 
1265 else 
1266 ifdef_level--; 
1267 } else { 
1268 static const struct directives { 
1269 int size; 
1270 const char *string; 
1271 } recognized[] = { 
1272 {7, "include"}, 
1273 {6, "define"}, 
1274 {5, "undef"}, 
1275 {4, "line"}, 
1276 {5, "error"}, 
1277 {6, "pragma"} 
1278 }; 
1279 int d = nitems(recognized); 
1280 while (--d >= 0) 
1281 if (strncmp(s_lab + 1, recognized[d].string, recognized[d].size) == 0) 
1282 break; 
1283 if (d < 0) { 
1284 diag(1, "Unrecognized cpp directive"); 
1285 break; 
1286 } 
1287 } 
1288 if (opt.blanklines_around_conditional_compilation) { 
1289 postfix_blankline_requested++; 
1290 n_real_blanklines = 0; 
1291 } else { 
1292 postfix_blankline_requested = 0; 
1293 prefix_blankline_requested = 0; 
1294 } 
1295 break; /* subsequent processing of the newline 
1296 * character will cause the line to be printed */ 
1297 
1298 case comment: /* we have gotten a / followed by * this is a biggie */ 
1299 pr_comment(); 1439 pr_comment();
1300 break; 1440 break;
1301 1441
1302 default: 1442 default:
1303 break; 1443 break;
1304 } /* end of big switch stmt */ 1444 } /* end of big switch stmt */
1305 1445
1306 *e_code = '\0'; /* make sure code section is null terminated */ 1446 *e_code = '\0'; /* make sure code section is null terminated */
1307 if (type_code != comment && 1447 if (type_code != comment &&
1308 type_code != newline && 1448 type_code != newline &&
1309 type_code != preprocessing) 1449 type_code != preprocessing)
1310 ps.last_token = type_code; 1450 ps.last_token = type_code;
1311 } 1451 }