| @@ -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 |
42 | static char sccsid[] = "@(#)indent.c 5.17 (Berkeley) 6/7/93"; | | 42 | static 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 | |
545 | static void | | 545 | static void |
| | | 546 | process_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 | |
| | | 565 | static void |
| | | 566 | process_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 | |
| | | 598 | static void |
| | | 599 | process_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 | |
| | | 606 | static void |
| | | 607 | process_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 | |
| | | 617 | static void |
| | | 618 | process_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 | |
| | | 661 | static void |
| | | 662 | process_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 | |
| | | 698 | static void |
| | | 699 | process_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 | |
| | | 727 | static void |
| | | 728 | process_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 | |
| | | 741 | static void |
| | | 742 | process_postfix_op(void) |
| | | 743 | { |
| | | 744 | *e_code++ = token[0]; |
| | | 745 | *e_code++ = token[1]; |
| | | 746 | ps.want_blank = true; |
| | | 747 | } |
| | | 748 | |
| | | 749 | static void |
| | | 750 | process_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 | |
| | | 761 | static void |
| | | 762 | process_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 | |
| | | 801 | static void |
| | | 802 | process_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 | |
| | | 857 | static void |
| | | 858 | process_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 | |
| | | 930 | static void |
| | | 931 | process_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 | |
| | | 966 | static void |
| | | 967 | process_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 | |
| | | 993 | static void |
| | | 994 | process_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 | |
| | | 1027 | static void |
| | | 1028 | process_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 | |
| | | 1057 | static void |
| | | 1058 | copy_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 | |
| | | 1069 | static void |
| | | 1070 | process_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 | |
| | | 1083 | static void |
| | | 1084 | process_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 | |
| | | 1090 | static void |
| | | 1091 | process_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 | |
| | | 1113 | static void |
| | | 1114 | process_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 | |
| | | 1258 | static void |
546 | main_loop(void) | | 1259 | main_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 | } |