Index: head/usr.bin/indent/args.c =================================================================== --- head/usr.bin/indent/args.c (revision 334926) +++ head/usr.bin/indent/args.c (revision 334927) @@ -1,354 +1,354 @@ /*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright (c) 1985 Sun Microsystems, Inc. * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if 0 #ifndef lint static char sccsid[] = "@(#)args.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ #endif #include __FBSDID("$FreeBSD$"); /* * Argument scanning and profile reading code. Default parameters are set * here as well. */ #include #include #include #include #include #include #include "indent_globs.h" #include "indent.h" #define INDENT_VERSION "2.0" /* profile types */ #define PRO_SPECIAL 1 /* special case */ #define PRO_BOOL 2 /* boolean */ #define PRO_INT 3 /* integer */ /* profile specials for booleans */ #define ON 1 /* turn it on */ #define OFF 0 /* turn it off */ /* profile specials for specials */ #define IGN 1 /* ignore it */ #define CLI 2 /* case label indent (float) */ #define STDIN 3 /* use stdin */ #define KEY 4 /* type (keyword) */ static void scan_profile(FILE *); #define KEY_FILE 5 /* only used for args */ #define VERSION 6 /* only used for args */ const char *option_source = "?"; void add_typedefs_from_file(const char *str); /* * N.B.: because of the way the table here is scanned, options whose names are * substrings of other options must occur later; that is, with -lp vs -l, -lp * must be first. Also, while (most) booleans occur more than once, the last * default value is the one actually assigned. */ struct pro { const char *p_name; /* name, e.g. -bl, -cli */ int p_type; /* type (int, bool, special) */ int p_default; /* the default value (if int) */ int p_special; /* depends on type */ int *p_obj; /* the associated variable */ } pro[] = { {"T", PRO_SPECIAL, 0, KEY, 0}, {"U", PRO_SPECIAL, 0, KEY_FILE, 0}, {"-version", PRO_SPECIAL, 0, VERSION, 0}, {"P", PRO_SPECIAL, 0, IGN, 0}, - {"bacc", PRO_BOOL, false, ON, &blanklines_around_conditional_compilation}, - {"badp", PRO_BOOL, false, ON, &blanklines_after_declarations_at_proctop}, - {"bad", PRO_BOOL, false, ON, &blanklines_after_declarations}, - {"bap", PRO_BOOL, false, ON, &blanklines_after_procs}, - {"bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments}, - {"bc", PRO_BOOL, true, OFF, &ps.leave_comma}, - {"bl", PRO_BOOL, true, OFF, &btype_2}, - {"br", PRO_BOOL, true, ON, &btype_2}, - {"bs", PRO_BOOL, false, ON, &Bill_Shannon}, - {"cdb", PRO_BOOL, true, ON, &comment_delimiter_on_blankline}, - {"cd", PRO_INT, 0, 0, &ps.decl_com_ind}, - {"ce", PRO_BOOL, true, ON, &cuddle_else}, - {"ci", PRO_INT, 0, 0, &continuation_indent}, + {"bacc", PRO_BOOL, false, ON, &opt.blanklines_around_conditional_compilation}, + {"badp", PRO_BOOL, false, ON, &opt.blanklines_after_declarations_at_proctop}, + {"bad", PRO_BOOL, false, ON, &opt.blanklines_after_declarations}, + {"bap", PRO_BOOL, false, ON, &opt.blanklines_after_procs}, + {"bbb", PRO_BOOL, false, ON, &opt.blanklines_before_blockcomments}, + {"bc", PRO_BOOL, true, OFF, &opt.leave_comma}, + {"bl", PRO_BOOL, true, OFF, &opt.btype_2}, + {"br", PRO_BOOL, true, ON, &opt.btype_2}, + {"bs", PRO_BOOL, false, ON, &opt.Bill_Shannon}, + {"cdb", PRO_BOOL, true, ON, &opt.comment_delimiter_on_blankline}, + {"cd", PRO_INT, 0, 0, &opt.decl_com_ind}, + {"ce", PRO_BOOL, true, ON, &opt.cuddle_else}, + {"ci", PRO_INT, 0, 0, &opt.continuation_indent}, {"cli", PRO_SPECIAL, 0, CLI, 0}, - {"c", PRO_INT, 33, 0, &ps.com_ind}, - {"di", PRO_INT, 16, 0, &ps.decl_indent}, - {"dj", PRO_BOOL, false, ON, &ps.ljust_decl}, - {"d", PRO_INT, 0, 0, &ps.unindent_displace}, - {"eei", PRO_BOOL, false, ON, &extra_expression_indent}, - {"ei", PRO_BOOL, true, ON, &ps.else_if}, - {"fbs", PRO_BOOL, true, ON, &function_brace_split}, - {"fc1", PRO_BOOL, true, ON, &format_col1_comments}, - {"fcb", PRO_BOOL, true, ON, &format_block_comments}, - {"ip", PRO_BOOL, true, ON, &ps.indent_parameters}, - {"i", PRO_INT, 8, 0, &ps.ind_size}, - {"lc", PRO_INT, 0, 0, &block_comment_max_col}, - {"ldi", PRO_INT, -1, 0, &ps.local_decl_indent}, - {"lpl", PRO_BOOL, false, ON, &lineup_to_parens_always}, - {"lp", PRO_BOOL, true, ON, &lineup_to_parens}, - {"l", PRO_INT, 78, 0, &max_col}, - {"nbacc", PRO_BOOL, false, OFF, &blanklines_around_conditional_compilation}, - {"nbadp", PRO_BOOL, false, OFF, &blanklines_after_declarations_at_proctop}, - {"nbad", PRO_BOOL, false, OFF, &blanklines_after_declarations}, - {"nbap", PRO_BOOL, false, OFF, &blanklines_after_procs}, - {"nbbb", PRO_BOOL, false, OFF, &blanklines_before_blockcomments}, - {"nbc", PRO_BOOL, true, ON, &ps.leave_comma}, - {"nbs", PRO_BOOL, false, OFF, &Bill_Shannon}, - {"ncdb", PRO_BOOL, true, OFF, &comment_delimiter_on_blankline}, - {"nce", PRO_BOOL, true, OFF, &cuddle_else}, - {"ndj", PRO_BOOL, false, OFF, &ps.ljust_decl}, - {"neei", PRO_BOOL, false, OFF, &extra_expression_indent}, - {"nei", PRO_BOOL, true, OFF, &ps.else_if}, - {"nfbs", PRO_BOOL, true, OFF, &function_brace_split}, - {"nfc1", PRO_BOOL, true, OFF, &format_col1_comments}, - {"nfcb", PRO_BOOL, true, OFF, &format_block_comments}, - {"nip", PRO_BOOL, true, OFF, &ps.indent_parameters}, - {"nlpl", PRO_BOOL, false, OFF, &lineup_to_parens_always}, - {"nlp", PRO_BOOL, true, OFF, &lineup_to_parens}, - {"npcs", PRO_BOOL, false, OFF, &proc_calls_space}, + {"c", PRO_INT, 33, 0, &opt.com_ind}, + {"di", PRO_INT, 16, 0, &opt.decl_indent}, + {"dj", PRO_BOOL, false, ON, &opt.ljust_decl}, + {"d", PRO_INT, 0, 0, &opt.unindent_displace}, + {"eei", PRO_BOOL, false, ON, &opt.extra_expression_indent}, + {"ei", PRO_BOOL, true, ON, &opt.else_if}, + {"fbs", PRO_BOOL, true, ON, &opt.function_brace_split}, + {"fc1", PRO_BOOL, true, ON, &opt.format_col1_comments}, + {"fcb", PRO_BOOL, true, ON, &opt.format_block_comments}, + {"ip", PRO_BOOL, true, ON, &opt.indent_parameters}, + {"i", PRO_INT, 8, 0, &opt.ind_size}, + {"lc", PRO_INT, 0, 0, &opt.block_comment_max_col}, + {"ldi", PRO_INT, -1, 0, &opt.local_decl_indent}, + {"lpl", PRO_BOOL, false, ON, &opt.lineup_to_parens_always}, + {"lp", PRO_BOOL, true, ON, &opt.lineup_to_parens}, + {"l", PRO_INT, 78, 0, &opt.max_col}, + {"nbacc", PRO_BOOL, false, OFF, &opt.blanklines_around_conditional_compilation}, + {"nbadp", PRO_BOOL, false, OFF, &opt.blanklines_after_declarations_at_proctop}, + {"nbad", PRO_BOOL, false, OFF, &opt.blanklines_after_declarations}, + {"nbap", PRO_BOOL, false, OFF, &opt.blanklines_after_procs}, + {"nbbb", PRO_BOOL, false, OFF, &opt.blanklines_before_blockcomments}, + {"nbc", PRO_BOOL, true, ON, &opt.leave_comma}, + {"nbs", PRO_BOOL, false, OFF, &opt.Bill_Shannon}, + {"ncdb", PRO_BOOL, true, OFF, &opt.comment_delimiter_on_blankline}, + {"nce", PRO_BOOL, true, OFF, &opt.cuddle_else}, + {"ndj", PRO_BOOL, false, OFF, &opt.ljust_decl}, + {"neei", PRO_BOOL, false, OFF, &opt.extra_expression_indent}, + {"nei", PRO_BOOL, true, OFF, &opt.else_if}, + {"nfbs", PRO_BOOL, true, OFF, &opt.function_brace_split}, + {"nfc1", PRO_BOOL, true, OFF, &opt.format_col1_comments}, + {"nfcb", PRO_BOOL, true, OFF, &opt.format_block_comments}, + {"nip", PRO_BOOL, true, OFF, &opt.indent_parameters}, + {"nlpl", PRO_BOOL, false, OFF, &opt.lineup_to_parens_always}, + {"nlp", PRO_BOOL, true, OFF, &opt.lineup_to_parens}, + {"npcs", PRO_BOOL, false, OFF, &opt.proc_calls_space}, {"npro", PRO_SPECIAL, 0, IGN, 0}, - {"npsl", PRO_BOOL, true, OFF, &procnames_start_line}, - {"nsac", PRO_BOOL, false, OFF, &space_after_cast}, - {"nsc", PRO_BOOL, true, OFF, &star_comment_cont}, - {"nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines}, - {"nut", PRO_BOOL, true, OFF, &use_tabs}, - {"nv", PRO_BOOL, false, OFF, &verbose}, - {"pcs", PRO_BOOL, false, ON, &proc_calls_space}, - {"psl", PRO_BOOL, true, ON, &procnames_start_line}, - {"sac", PRO_BOOL, false, ON, &space_after_cast}, - {"sc", PRO_BOOL, true, ON, &star_comment_cont}, - {"sob", PRO_BOOL, false, ON, &swallow_optional_blanklines}, + {"npsl", PRO_BOOL, true, OFF, &opt.procnames_start_line}, + {"nsac", PRO_BOOL, false, OFF, &opt.space_after_cast}, + {"nsc", PRO_BOOL, true, OFF, &opt.star_comment_cont}, + {"nsob", PRO_BOOL, false, OFF, &opt.swallow_optional_blanklines}, + {"nut", PRO_BOOL, true, OFF, &opt.use_tabs}, + {"nv", PRO_BOOL, false, OFF, &opt.verbose}, + {"pcs", PRO_BOOL, false, ON, &opt.proc_calls_space}, + {"psl", PRO_BOOL, true, ON, &opt.procnames_start_line}, + {"sac", PRO_BOOL, false, ON, &opt.space_after_cast}, + {"sc", PRO_BOOL, true, ON, &opt.star_comment_cont}, + {"sob", PRO_BOOL, false, ON, &opt.swallow_optional_blanklines}, {"st", PRO_SPECIAL, 0, STDIN, 0}, - {"ta", PRO_BOOL, false, ON, &auto_typedefs}, - {"ts", PRO_INT, 8, 0, &tabsize}, - {"ut", PRO_BOOL, true, ON, &use_tabs}, - {"v", PRO_BOOL, false, ON, &verbose}, + {"ta", PRO_BOOL, false, ON, &opt.auto_typedefs}, + {"ts", PRO_INT, 8, 0, &opt.tabsize}, + {"ut", PRO_BOOL, true, ON, &opt.use_tabs}, + {"v", PRO_BOOL, false, ON, &opt.verbose}, /* whew! */ {0, 0, 0, 0, 0} }; /* * set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments * given in these files. */ void set_profile(const char *profile_name) { FILE *f; char fname[PATH_MAX]; static char prof[] = ".indent.pro"; if (profile_name == NULL) snprintf(fname, sizeof(fname), "%s/%s", getenv("HOME"), prof); else snprintf(fname, sizeof(fname), "%s", profile_name + 2); if ((f = fopen(option_source = fname, "r")) != NULL) { scan_profile(f); (void) fclose(f); } if ((f = fopen(option_source = prof, "r")) != NULL) { scan_profile(f); (void) fclose(f); } option_source = "Command line"; } static void scan_profile(FILE *f) { int comment, i; char *p; char buf[BUFSIZ]; while (1) { p = buf; comment = 0; while ((i = getc(f)) != EOF) { if (i == '*' && !comment && p > buf && p[-1] == '/') { comment = p - buf; *p++ = i; } else if (i == '/' && comment && p > buf && p[-1] == '*') { p = buf + comment - 1; comment = 0; } else if (isspace((unsigned char)i)) { if (p > buf && !comment) break; } else { *p++ = i; } } if (p != buf) { *p++ = 0; - if (verbose) + if (opt.verbose) printf("profile: %s\n", buf); set_option(buf); } else if (i == EOF) return; } } static const char * eqin(const char *s1, const char *s2) { while (*s1) { if (*s1++ != *s2++) return (NULL); } return (s2); } /* * Set the defaults. */ void set_defaults(void) { struct pro *p; /* * Because ps.case_indent is a float, we can't initialize it from the * table: */ ps.case_indent = 0.0; /* -cli0.0 */ for (p = pro; p->p_name; p++) if (p->p_type != PRO_SPECIAL) *p->p_obj = p->p_default; } void set_option(char *arg) { struct pro *p; const char *param_start; arg++; /* ignore leading "-" */ for (p = pro; p->p_name; p++) if (*p->p_name == *arg && (param_start = eqin(p->p_name, arg)) != NULL) goto found; errx(1, "%s: unknown parameter \"%s\"", option_source, arg - 1); found: switch (p->p_type) { case PRO_SPECIAL: switch (p->p_special) { case IGN: break; case CLI: if (*param_start == 0) goto need_param; ps.case_indent = atof(param_start); break; case STDIN: if (input == NULL) input = stdin; if (output == NULL) output = stdout; break; case KEY: if (*param_start == 0) goto need_param; add_typename(param_start); break; case KEY_FILE: if (*param_start == 0) goto need_param; add_typedefs_from_file(param_start); break; case VERSION: printf("FreeBSD indent %s\n", INDENT_VERSION); exit(0); default: errx(1, "set_option: internal error: p_special %d", p->p_special); } break; case PRO_BOOL: if (p->p_special == OFF) *p->p_obj = false; else *p->p_obj = true; break; case PRO_INT: if (!isdigit((unsigned char)*param_start)) { need_param: errx(1, "%s: ``%s'' requires a parameter", option_source, p->p_name); } *p->p_obj = atoi(param_start); break; default: errx(1, "set_option: internal error: p_type %d", p->p_type); } } void add_typedefs_from_file(const char *str) { FILE *file; char line[BUFSIZ]; if ((file = fopen(str, "r")) == NULL) { fprintf(stderr, "indent: cannot open file %s\n", str); exit(1); } while ((fgets(line, BUFSIZ, file)) != NULL) { /* Remove trailing whitespace */ line[strcspn(line, " \t\n\r")] = '\0'; add_typename(line); } fclose(file); } Index: head/usr.bin/indent/indent.c =================================================================== --- head/usr.bin/indent/indent.c (revision 334926) +++ head/usr.bin/indent/indent.c (revision 334927) @@ -1,1291 +1,1291 @@ /*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright (c) 1985 Sun Microsystems, Inc. * Copyright (c) 1976 Board of Trustees of the University of Illinois. * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if 0 #ifndef lint static char sccsid[] = "@(#)indent.c 5.17 (Berkeley) 6/7/93"; #endif /* not lint */ #endif #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include "indent_globs.h" #include "indent_codes.h" #include "indent.h" static void bakcopy(void); static void indent_declaration(int, int); const char *in_name = "Standard Input"; /* will always point to name of input * file */ const char *out_name = "Standard Output"; /* will always point to name * of output file */ const char *simple_backup_suffix = ".BAK"; /* Suffix to use for backup * files */ char bakfile[MAXPATHLEN] = ""; int main(int argc, char **argv) { cap_rights_t rights; int dec_ind; /* current indentation for declarations */ int di_stack[20]; /* a stack of structure indentation levels */ int force_nl; /* when true, code must be broken */ int hd_type = 0; /* used to store type of stmt for if (...), * for (...), etc */ int i; /* local loop counter */ int scase; /* set to true when we see a case, so we will * know what to do with the following colon */ int sp_sw; /* when true, we are in the expression of * if(...), while(...), etc. */ int squest; /* when this is positive, we have seen a ? * without the matching : in a ?: * construct */ const char *t_ptr; /* used for copying tokens */ int tabs_to_var; /* true if using tabs to indent to var name */ int type_code; /* the type of token, returned by lexi */ int last_else = 0; /* true iff last keyword was an else */ const char *profile_name = NULL; const char *envval = NULL; struct parser_state transient_state; /* a copy for lookup */ /*-----------------------------------------------*\ | INITIALIZATION | \*-----------------------------------------------*/ found_err = 0; ps.p_stack[0] = stmt; /* this is the parser's stack */ ps.last_nl = true; /* this is true if the last thing scanned was * a newline */ ps.last_token = semicolon; combuf = (char *) malloc(bufsize); if (combuf == NULL) err(1, NULL); labbuf = (char *) malloc(bufsize); if (labbuf == NULL) err(1, NULL); codebuf = (char *) malloc(bufsize); if (codebuf == NULL) err(1, NULL); tokenbuf = (char *) malloc(bufsize); if (tokenbuf == NULL) err(1, NULL); alloc_typenames(); l_com = combuf + bufsize - 5; l_lab = labbuf + bufsize - 5; l_code = codebuf + bufsize - 5; l_token = tokenbuf + bufsize - 5; combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and * comment buffers */ combuf[1] = codebuf[1] = labbuf[1] = '\0'; - ps.else_if = 1; /* Default else-if special processing to on */ + opt.else_if = 1; /* Default else-if special processing to on */ s_lab = e_lab = labbuf + 1; s_code = e_code = codebuf + 1; s_com = e_com = combuf + 1; s_token = e_token = tokenbuf + 1; in_buffer = (char *) malloc(10); if (in_buffer == NULL) err(1, NULL); in_buffer_limit = in_buffer + 8; buf_ptr = buf_end = in_buffer; line_no = 1; had_eof = ps.in_decl = ps.decl_on_line = break_comma = false; sp_sw = force_nl = false; ps.in_or_st = false; ps.bl_line = true; dec_ind = 0; di_stack[ps.dec_nest = 0] = 0; ps.want_blank = ps.in_stmt = ps.ind_stmt = false; scase = ps.pcase = false; squest = 0; sc_end = NULL; bp_save = NULL; be_save = NULL; output = NULL; tabs_to_var = 0; envval = getenv("SIMPLE_BACKUP_SUFFIX"); if (envval) simple_backup_suffix = envval; /*--------------------------------------------------*\ | COMMAND LINE SCAN | \*--------------------------------------------------*/ #ifdef undef max_col = 78; /* -l78 */ lineup_to_parens = 1; /* -lp */ lineup_to_parens_always = 0; /* -nlpl */ ps.ljust_decl = 0; /* -ndj */ ps.com_ind = 33; /* -c33 */ star_comment_cont = 1; /* -sc */ ps.ind_size = 8; /* -i8 */ verbose = 0; ps.decl_indent = 16; /* -di16 */ ps.local_decl_indent = -1; /* if this is not set to some nonnegative value * by an arg, we will set this equal to * ps.decl_ind */ ps.indent_parameters = 1; /* -ip */ ps.decl_com_ind = 0; /* if this is not set to some positive value * by an arg, we will set this equal to * ps.com_ind */ btype_2 = 1; /* -br */ cuddle_else = 1; /* -ce */ ps.unindent_displace = 0; /* -d0 */ ps.case_indent = 0; /* -cli0 */ format_block_comments = 1; /* -fcb */ format_col1_comments = 1; /* -fc1 */ procnames_start_line = 1; /* -psl */ proc_calls_space = 0; /* -npcs */ comment_delimiter_on_blankline = 1; /* -cdb */ ps.leave_comma = 1; /* -nbc */ #endif for (i = 1; i < argc; ++i) if (strcmp(argv[i], "-npro") == 0) break; else if (argv[i][0] == '-' && argv[i][1] == 'P' && argv[i][2] != '\0') profile_name = argv[i]; /* non-empty -P (set profile) */ set_defaults(); if (i >= argc) set_profile(profile_name); for (i = 1; i < argc; ++i) { /* * look thru args (if any) for changes to defaults */ if (argv[i][0] != '-') {/* no flag on parameter */ if (input == NULL) { /* we must have the input file */ in_name = argv[i]; /* remember name of input file */ input = fopen(in_name, "r"); if (input == NULL) /* check for open error */ err(1, "%s", in_name); continue; } else if (output == NULL) { /* we have the output file */ out_name = argv[i]; /* remember name of output file */ if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite * the file */ errx(1, "input and output files must be different"); } output = fopen(out_name, "w"); if (output == NULL) /* check for create error */ err(1, "%s", out_name); continue; } errx(1, "unknown parameter: %s", argv[i]); } else set_option(argv[i]); } /* end of for */ if (input == NULL) input = stdin; if (output == NULL) { if (input == stdin) output = stdout; else { out_name = in_name; bakcopy(); } } /* Restrict input/output descriptors and enter Capsicum sandbox. */ cap_rights_init(&rights, CAP_FSTAT, CAP_WRITE); if (cap_rights_limit(fileno(output), &rights) < 0 && errno != ENOSYS) err(EXIT_FAILURE, "unable to limit rights for %s", out_name); cap_rights_init(&rights, CAP_FSTAT, CAP_READ); if (cap_rights_limit(fileno(input), &rights) < 0 && errno != ENOSYS) err(EXIT_FAILURE, "unable to limit rights for %s", in_name); if (cap_enter() < 0 && errno != ENOSYS) err(EXIT_FAILURE, "unable to enter capability mode"); - if (ps.com_ind <= 1) - ps.com_ind = 2; /* dont put normal comments before column 2 */ - if (block_comment_max_col <= 0) - block_comment_max_col = max_col; - if (ps.local_decl_indent < 0) /* if not specified by user, set this */ - ps.local_decl_indent = ps.decl_indent; - if (ps.decl_com_ind <= 0) /* if not specified by user, set this */ - ps.decl_com_ind = ps.ljust_decl ? (ps.com_ind <= 10 ? 2 : ps.com_ind - 8) : ps.com_ind; - if (continuation_indent == 0) - continuation_indent = ps.ind_size; + if (opt.com_ind <= 1) + opt.com_ind = 2; /* don't put normal comments before column 2 */ + if (opt.block_comment_max_col <= 0) + opt.block_comment_max_col = opt.max_col; + if (opt.local_decl_indent < 0) /* if not specified by user, set this */ + opt.local_decl_indent = opt.decl_indent; + if (opt.decl_com_ind <= 0) /* if not specified by user, set this */ + opt.decl_com_ind = opt.ljust_decl ? (opt.com_ind <= 10 ? 2 : opt.com_ind - 8) : opt.com_ind; + if (opt.continuation_indent == 0) + opt.continuation_indent = opt.ind_size; fill_buffer(); /* get first batch of stuff into input buffer */ parse(semicolon); { char *p = buf_ptr; int col = 1; while (1) { if (*p == ' ') col++; else if (*p == '\t') - col = tabsize * (1 + (col - 1) / tabsize) + 1; + col = opt.tabsize * (1 + (col - 1) / opt.tabsize) + 1; else break; p++; } - if (col > ps.ind_size) - ps.ind_level = ps.i_l_follow = col / ps.ind_size; + if (col > opt.ind_size) + ps.ind_level = ps.i_l_follow = col / opt.ind_size; } /* * START OF MAIN LOOP */ while (1) { /* this is the main loop. it will go until we * reach eof */ int comment_buffered = false; type_code = lexi(&ps); /* lexi reads one token. The actual * characters read are stored in "token". lexi * returns a code indicating the type of token */ /* * The following code moves newlines and comments following an if (), * while (), else, etc. up to the start of the following stmt to * a buffer. This allows proper handling of both kinds of brace * placement (-br, -bl) and cuddling "else" (-ce). */ while (ps.search_brace) { switch (type_code) { case newline: if (sc_end == NULL) { save_com = sc_buf; save_com[0] = save_com[1] = ' '; sc_end = &save_com[2]; } *sc_end++ = '\n'; /* * We may have inherited a force_nl == true from the previous * token (like a semicolon). But once we know that a newline * has been scanned in this loop, force_nl should be false. * * However, the force_nl == true must be preserved if newline * is never scanned in this loop, so this assignment cannot be * done earlier. */ force_nl = false; case form_feed: break; case comment: if (sc_end == NULL) { /* * Copy everything from the start of the line, because * pr_comment() will use that to calculate original * indentation of a boxed comment. */ memcpy(sc_buf, in_buffer, buf_ptr - in_buffer - 4); save_com = sc_buf + (buf_ptr - in_buffer - 4); save_com[0] = save_com[1] = ' '; sc_end = &save_com[2]; } comment_buffered = true; *sc_end++ = '/'; /* copy in start of comment */ *sc_end++ = '*'; for (;;) { /* loop until we get to the end of the comment */ *sc_end = *buf_ptr++; if (buf_ptr >= buf_end) fill_buffer(); if (*sc_end++ == '*' && *buf_ptr == '/') break; /* we are at end of comment */ if (sc_end >= &save_com[sc_size]) { /* check for temp buffer * overflow */ diag2(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever"); fflush(output); exit(1); } } *sc_end++ = '/'; /* add ending slash */ if (++buf_ptr >= buf_end) /* get past / in buffer */ fill_buffer(); break; case lbrace: /* * Put KNF-style lbraces before the buffered up tokens and * jump out of this loop in order to avoid copying the token * again under the default case of the switch below. */ - if (sc_end != NULL && btype_2) { + if (sc_end != NULL && opt.btype_2) { save_com[0] = '{'; /* * Originally the lbrace may have been alone on its own * line, but it will be moved into "the else's line", so * if there was a newline resulting from the "{" before, * it must be scanned now and ignored. */ while (isspace((unsigned char)*buf_ptr)) { if (++buf_ptr >= buf_end) fill_buffer(); if (*buf_ptr == '\n') break; } goto sw_buffer; } /* FALLTHROUGH */ default: /* it is the start of a normal statement */ { int remove_newlines; remove_newlines = /* "} else" */ (type_code == sp_nparen && *token == 'e' && e_code != s_code && e_code[-1] == '}') /* "else if" */ || (type_code == sp_paren && *token == 'i' && - last_else && ps.else_if); + last_else && opt.else_if); if (remove_newlines) force_nl = false; if (sc_end == NULL) { /* ignore buffering if * comment wasn't saved up */ ps.search_brace = false; goto check_type; } while (sc_end > save_com && isblank((unsigned char)sc_end[-1])) { sc_end--; } - if (swallow_optional_blanklines || + if (opt.swallow_optional_blanklines || (!comment_buffered && remove_newlines)) { force_nl = !remove_newlines; while (sc_end > save_com && sc_end[-1] == '\n') { sc_end--; } } if (force_nl) { /* if we should insert a nl here, put * it into the buffer */ force_nl = false; --line_no; /* this will be re-increased when the * newline is read from the buffer */ *sc_end++ = '\n'; *sc_end++ = ' '; - if (verbose) /* print error msg if the line was + if (opt.verbose) /* print error msg if the line was * not already broken */ diag2(0, "Line broken"); } for (t_ptr = token; *t_ptr; ++t_ptr) *sc_end++ = *t_ptr; sw_buffer: ps.search_brace = false; /* stop looking for start of * stmt */ bp_save = buf_ptr; /* save current input buffer */ be_save = buf_end; buf_ptr = save_com; /* fix so that subsequent calls to * lexi will take tokens out of * save_com */ *sc_end++ = ' ';/* add trailing blank, just in case */ buf_end = sc_end; sc_end = NULL; break; } } /* end of switch */ /* * We must make this check, just in case there was an unexpected * EOF. */ if (type_code != 0) { /* * The only intended purpose of calling lexi() below is to * categorize the next token in order to decide whether to * continue buffering forthcoming tokens. Once the buffering * is over, lexi() will be called again elsewhere on all of * the tokens - this time for normal processing. * * Calling it for this purpose is a bug, because lexi() also * changes the parser state and discards leading whitespace, * which is needed mostly for comment-related considerations. * * Work around the former problem by giving lexi() a copy of * the current parser state and discard it if the call turned * out to be just a look ahead. * * Work around the latter problem by copying all whitespace * characters into the buffer so that the later lexi() call * will read them. */ if (sc_end != NULL) { while (*buf_ptr == ' ' || *buf_ptr == '\t') { *sc_end++ = *buf_ptr++; if (sc_end >= &save_com[sc_size]) { errx(1, "input too long"); } } if (buf_ptr >= buf_end) { fill_buffer(); } } transient_state = ps; type_code = lexi(&transient_state); /* read another token */ if (type_code != newline && type_code != form_feed && type_code != comment && !transient_state.search_brace) { ps = transient_state; } } } /* end of while (search_brace) */ last_else = 0; check_type: if (type_code == 0) { /* we got eof */ if (s_lab != e_lab || s_code != e_code || s_com != e_com) /* must dump end of line */ dump_line(); if (ps.tos > 1) /* check for balanced braces */ diag2(1, "Stuff missing from end of file"); - if (verbose) { + if (opt.verbose) { printf("There were %d output lines and %d comments\n", ps.out_lines, ps.out_coms); printf("(Lines with comments)/(Lines with code): %6.3f\n", (1.0 * ps.com_lines) / code_lines); } fflush(output); exit(found_err); } if ( (type_code != comment) && (type_code != newline) && (type_code != preesc) && (type_code != form_feed)) { if (force_nl && (type_code != semicolon) && - (type_code != lbrace || !btype_2)) { + (type_code != lbrace || !opt.btype_2)) { /* we should force a broken line here */ - if (verbose) + if (opt.verbose) diag2(0, "Line broken"); dump_line(); ps.want_blank = false; /* dont insert blank at line start */ force_nl = false; } ps.in_stmt = true; /* turn on flag which causes an extra level of * indentation. this is turned off by a ; or * '}' */ if (s_com != e_com) { /* the turkey has embedded a comment * in a line. fix it */ int len = e_com - s_com; CHECK_SIZE_CODE(len + 3); *e_code++ = ' '; memcpy(e_code, s_com, len); e_code += len; *e_code++ = ' '; *e_code = '\0'; /* null terminate code sect */ ps.want_blank = false; e_com = s_com; } } else if (type_code != comment) /* preserve force_nl thru a comment */ force_nl = false; /* cancel forced newline after newline, form * feed, etc */ /*-----------------------------------------------------*\ | do switch on type of token scanned | \*-----------------------------------------------------*/ CHECK_SIZE_CODE(3); /* maximum number of increments of e_code * before the next CHECK_SIZE_CODE or * dump_line() is 2. After that there's the * final increment for the null character. */ switch (type_code) { /* now, decide what to do with the token */ case form_feed: /* found a form feed in line */ ps.use_ff = true; /* a form feed is treated much like a newline */ dump_line(); ps.want_blank = false; break; case newline: if (ps.last_token != comma || ps.p_l_follow > 0 - || !ps.leave_comma || ps.block_init || !break_comma || s_com != e_com) { + || !opt.leave_comma || ps.block_init || !break_comma || s_com != e_com) { dump_line(); ps.want_blank = false; } ++line_no; /* keep track of input line number */ break; case lparen: /* got a '(' or '[' */ /* count parens to make Healy happy */ if (++ps.p_l_follow == nitems(ps.paren_indents)) { diag3(0, "Reached internal limit of %d unclosed parens", nitems(ps.paren_indents)); ps.p_l_follow--; } if (*token == '[') /* not a function pointer declaration or a function call */; else if (ps.in_decl && !ps.block_init && !ps.dumped_decl_indent && ps.procname[0] == '\0' && ps.paren_level == 0) { /* function pointer declarations */ indent_declaration(dec_ind, tabs_to_var); ps.dumped_decl_indent = true; } else if (ps.want_blank && ((ps.last_token != ident && ps.last_token != funcname) || - proc_calls_space || + opt.proc_calls_space || /* offsetof (1) is never allowed a space; sizeof (2) gets * one iff -bs; all other keywords (>2) always get a space * before lparen */ - ps.keyword + Bill_Shannon > 2)) + ps.keyword + opt.Bill_Shannon > 2)) *e_code++ = ' '; ps.want_blank = false; *e_code++ = token[0]; ps.paren_indents[ps.p_l_follow - 1] = count_spaces_until(1, s_code, e_code) - 1; - if (sp_sw && ps.p_l_follow == 1 && extra_expression_indent - && ps.paren_indents[0] < 2 * ps.ind_size) - ps.paren_indents[0] = 2 * ps.ind_size; + if (sp_sw && ps.p_l_follow == 1 && opt.extra_expression_indent + && ps.paren_indents[0] < 2 * opt.ind_size) + ps.paren_indents[0] = 2 * opt.ind_size; if (ps.in_or_st && *token == '(' && ps.tos <= 2) { /* * this is a kluge to make sure that declarations will be * aligned right if proc decl has an explicit type on it, i.e. * "int a(x) {..." */ parse(semicolon); /* I said this was a kluge... */ ps.in_or_st = false; /* turn off flag for structure decl or * initialization */ } /* parenthesized type following sizeof or offsetof is not a cast */ if (ps.keyword == 1 || ps.keyword == 2) ps.not_cast_mask |= 1 << ps.p_l_follow; break; case rparen: /* got a ')' or ']' */ if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.not_cast_mask) { ps.last_u_d = true; ps.cast_mask &= (1 << ps.p_l_follow) - 1; - ps.want_blank = space_after_cast; + ps.want_blank = opt.space_after_cast; } else ps.want_blank = true; ps.not_cast_mask &= (1 << ps.p_l_follow) - 1; if (--ps.p_l_follow < 0) { ps.p_l_follow = 0; diag3(0, "Extra %c", *token); } if (e_code == s_code) /* if the paren starts the line */ ps.paren_level = ps.p_l_follow; /* then indent it */ *e_code++ = token[0]; if (sp_sw && (ps.p_l_follow == 0)) { /* check for end of if * (...), or some such */ sp_sw = false; force_nl = true;/* must force newline after if */ ps.last_u_d = true; /* inform lexi that a following * operator is unary */ ps.in_stmt = false; /* dont use stmt continuation * indentation */ parse(hd_type); /* let parser worry about if, or whatever */ } - ps.search_brace = btype_2; /* this should insure that constructs - * such as main(){...} and int[]{...} - * have their braces put in the right - * place */ + ps.search_brace = opt.btype_2; /* this should ensure that + * constructs such as main(){...} + * and int[]{...} have their braces + * put in the right place */ break; case unary_op: /* this could be any unary operation */ if (!ps.dumped_decl_indent && ps.in_decl && !ps.block_init && ps.procname[0] == '\0' && ps.paren_level == 0) { /* pointer declarations */ /* * if this is a unary op in a declaration, we should indent * this token */ for (i = 0; token[i]; ++i) /* find length of token */; indent_declaration(dec_ind - i, tabs_to_var); ps.dumped_decl_indent = true; } else if (ps.want_blank) *e_code++ = ' '; { int len = e_token - s_token; CHECK_SIZE_CODE(len); memcpy(e_code, token, len); e_code += len; } ps.want_blank = false; break; case binary_op: /* any binary operation */ { int len = e_token - s_token; CHECK_SIZE_CODE(len + 1); if (ps.want_blank) *e_code++ = ' '; memcpy(e_code, token, len); e_code += len; } ps.want_blank = true; break; case postop: /* got a trailing ++ or -- */ *e_code++ = token[0]; *e_code++ = token[1]; ps.want_blank = true; break; case question: /* got a ? */ squest++; /* this will be used when a later colon * appears so we can distinguish the * ?: construct */ if (ps.want_blank) *e_code++ = ' '; *e_code++ = '?'; ps.want_blank = true; break; case casestmt: /* got word 'case' or 'default' */ scase = true; /* so we can process the later colon properly */ goto copy_id; case colon: /* got a ':' */ if (squest > 0) { /* it is part of the ?: construct */ --squest; if (ps.want_blank) *e_code++ = ' '; *e_code++ = ':'; ps.want_blank = true; break; } if (ps.in_or_st) { *e_code++ = ':'; ps.want_blank = false; break; } ps.in_stmt = false; /* seeing a label does not imply we are in a * stmt */ /* * turn everything so far into a label */ { int len = e_code - s_code; CHECK_SIZE_LAB(len + 3); memcpy(e_lab, s_code, len); e_lab += len; *e_lab++ = ':'; *e_lab = '\0'; e_code = s_code; } force_nl = ps.pcase = scase; /* ps.pcase will be used by * dump_line to decide how to * indent the label. force_nl * will force a case n: to be * on a line by itself */ scase = false; ps.want_blank = false; break; case semicolon: /* got a ';' */ if (ps.dec_nest == 0) ps.in_or_st = false;/* we are not in an initialization or * structure declaration */ scase = false; /* these will only need resetting in an error */ squest = 0; if (ps.last_token == rparen) ps.in_parameter_declaration = 0; ps.cast_mask = 0; ps.not_cast_mask = 0; ps.block_init = 0; ps.block_init_level = 0; ps.just_saw_decl--; if (ps.in_decl && s_code == e_code && !ps.block_init && !ps.dumped_decl_indent && ps.paren_level == 0) { /* indent stray semicolons in declarations */ indent_declaration(dec_ind - 1, tabs_to_var); ps.dumped_decl_indent = true; } ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level * structure declaration, we * arent any more */ if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) { /* * This should be true iff there were unbalanced parens in the * stmt. It is a bit complicated, because the semicolon might * be in a for stmt */ diag2(1, "Unbalanced parens"); ps.p_l_follow = 0; if (sp_sw) { /* this is a check for an if, while, etc. with * unbalanced parens */ sp_sw = false; parse(hd_type); /* dont lose the if, or whatever */ } } *e_code++ = ';'; ps.want_blank = true; ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the * middle of a stmt */ if (!sp_sw) { /* if not if for (;;) */ parse(semicolon); /* let parser know about end of stmt */ force_nl = true;/* force newline after an end of stmt */ } break; case lbrace: /* got a '{' */ ps.in_stmt = false; /* dont indent the {} */ if (!ps.block_init) force_nl = true;/* force other stuff on same line as '{' onto * new line */ else if (ps.block_init_level <= 0) ps.block_init_level = 1; else ps.block_init_level++; if (s_code != e_code && !ps.block_init) { - if (!btype_2) { + if (!opt.btype_2) { dump_line(); ps.want_blank = false; } else if (ps.in_parameter_declaration && !ps.in_or_st) { ps.i_l_follow = 0; - if (function_brace_split) { /* dump the line prior to the - * brace ... */ + if (opt.function_brace_split) { /* dump the line prior + * to the brace ... */ dump_line(); ps.want_blank = false; } else /* add a space between the decl and brace */ ps.want_blank = true; } } if (ps.in_parameter_declaration) prefix_blankline_requested = 0; if (ps.p_l_follow > 0) { /* check for preceding unbalanced * parens */ diag2(1, "Unbalanced parens"); ps.p_l_follow = 0; if (sp_sw) { /* check for unclosed if, for, etc. */ sp_sw = false; parse(hd_type); ps.ind_level = ps.i_l_follow; } } if (s_code == e_code) ps.ind_stmt = false; /* dont put extra indentation on line * with '{' */ if (ps.in_decl && ps.in_or_st) { /* this is either a structure * declaration or an init */ di_stack[ps.dec_nest] = dec_ind; if (++ps.dec_nest == nitems(di_stack)) { diag3(0, "Reached internal limit of %d struct levels", nitems(di_stack)); ps.dec_nest--; } /* ? dec_ind = 0; */ } else { ps.decl_on_line = false; /* we can't be in the middle of * a declaration, so don't do * special indentation of * comments */ - if (blanklines_after_declarations_at_proctop + if (opt.blanklines_after_declarations_at_proctop && ps.in_parameter_declaration) postfix_blankline_requested = 1; ps.in_parameter_declaration = 0; ps.in_decl = false; } dec_ind = 0; parse(lbrace); /* let parser know about this */ if (ps.want_blank) /* put a blank before '{' if '{' is not at * start of line */ *e_code++ = ' '; ps.want_blank = false; *e_code++ = '{'; ps.just_saw_decl = 0; break; case rbrace: /* got a '}' */ if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be * omitted in * declarations */ parse(semicolon); if (ps.p_l_follow) {/* check for unclosed if, for, else. */ diag2(1, "Unbalanced parens"); ps.p_l_follow = 0; sp_sw = false; } ps.just_saw_decl = 0; ps.block_init_level--; if (s_code != e_code && !ps.block_init) { /* '}' must be first on * line */ - if (verbose) + if (opt.verbose) diag2(0, "Line broken"); dump_line(); } *e_code++ = '}'; ps.want_blank = true; ps.in_stmt = ps.ind_stmt = false; if (ps.dec_nest > 0) { /* we are in multi-level structure * declaration */ dec_ind = di_stack[--ps.dec_nest]; if (ps.dec_nest == 0 && !ps.in_parameter_declaration) ps.just_saw_decl = 2; ps.in_decl = true; } prefix_blankline_requested = 0; parse(rbrace); /* let parser know about this */ - ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead + ps.search_brace = opt.cuddle_else && ps.p_stack[ps.tos] == ifhead && ps.il[ps.tos] >= ps.ind_level; - if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0) + if (ps.tos <= 1 && opt.blanklines_after_procs && ps.dec_nest <= 0) postfix_blankline_requested = 1; break; case swstmt: /* got keyword "switch" */ sp_sw = true; hd_type = swstmt; /* keep this for when we have seen the * expression */ goto copy_id; /* go move the token into buffer */ case sp_paren: /* token is if, while, for */ sp_sw = true; /* the interesting stuff is done after the * expression is scanned */ hd_type = (*token == 'i' ? ifstmt : (*token == 'w' ? whilestmt : forstmt)); /* * remember the type of header for later use by parser */ goto copy_id; /* copy the token into line */ case sp_nparen: /* got else, do */ ps.in_stmt = false; if (*token == 'e') { - if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) { - if (verbose) + if (e_code != s_code && (!opt.cuddle_else || e_code[-1] != '}')) { + if (opt.verbose) diag2(0, "Line broken"); dump_line();/* make sure this starts a line */ ps.want_blank = false; } force_nl = true;/* also, following stuff must go onto new line */ last_else = 1; parse(elselit); } else { if (e_code != s_code) { /* make sure this starts a line */ - if (verbose) + if (opt.verbose) diag2(0, "Line broken"); dump_line(); ps.want_blank = false; } force_nl = true;/* also, following stuff must go onto new line */ last_else = 0; parse(dolit); } goto copy_id; /* move the token into line */ case type_def: case storage: prefix_blankline_requested = 0; goto copy_id; case structure: if (ps.p_l_follow > 0) goto copy_id; case decl: /* we have a declaration type (int, etc.) */ parse(decl); /* let parser worry about indentation */ if (ps.last_token == rparen && ps.tos <= 1) { if (s_code != e_code) { dump_line(); ps.want_blank = 0; } } - if (ps.in_parameter_declaration && ps.indent_parameters && ps.dec_nest == 0) { + if (ps.in_parameter_declaration && opt.indent_parameters && ps.dec_nest == 0) { ps.ind_level = ps.i_l_follow = 1; ps.ind_stmt = 0; } ps.in_or_st = true; /* this might be a structure or initialization * declaration */ ps.in_decl = ps.decl_on_line = ps.last_token != type_def; if ( /* !ps.in_or_st && */ ps.dec_nest <= 0) ps.just_saw_decl = 2; prefix_blankline_requested = 0; for (i = 0; token[i++];); /* get length of token */ if (ps.ind_level == 0 || ps.dec_nest > 0) { /* global variable or struct member in local variable */ - dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i; - tabs_to_var = (use_tabs ? ps.decl_indent > 0 : 0); + dec_ind = opt.decl_indent > 0 ? opt.decl_indent : i; + tabs_to_var = (opt.use_tabs ? opt.decl_indent > 0 : 0); } else { /* local variable */ - dec_ind = ps.local_decl_indent > 0 ? ps.local_decl_indent : i; - tabs_to_var = (use_tabs ? ps.local_decl_indent > 0 : 0); + dec_ind = opt.local_decl_indent > 0 ? opt.local_decl_indent : i; + tabs_to_var = (opt.use_tabs ? opt.local_decl_indent > 0 : 0); } goto copy_id; case funcname: case ident: /* got an identifier or constant */ if (ps.in_decl) { if (type_code == funcname) { ps.in_decl = false; - if (procnames_start_line && s_code != e_code) { + if (opt.procnames_start_line && s_code != e_code) { *e_code = '\0'; dump_line(); } else if (ps.want_blank) { *e_code++ = ' '; } ps.want_blank = false; } else if (!ps.block_init && !ps.dumped_decl_indent && ps.paren_level == 0) { /* if we are in a declaration, we * must indent identifier */ indent_declaration(dec_ind, tabs_to_var); ps.dumped_decl_indent = true; ps.want_blank = false; } } else if (sp_sw && ps.p_l_follow == 0) { sp_sw = false; force_nl = true; ps.last_u_d = true; ps.in_stmt = false; parse(hd_type); } copy_id: { int len = e_token - s_token; CHECK_SIZE_CODE(len + 1); if (ps.want_blank) *e_code++ = ' '; memcpy(e_code, s_token, len); e_code += len; } if (type_code != funcname) ps.want_blank = true; break; case strpfx: { int len = e_token - s_token; CHECK_SIZE_CODE(len + 1); if (ps.want_blank) *e_code++ = ' '; memcpy(e_code, token, len); e_code += len; } ps.want_blank = false; break; case period: /* treat a period kind of like a binary * operation */ *e_code++ = '.'; /* move the period into line */ ps.want_blank = false; /* dont put a blank after a period */ break; case comma: ps.want_blank = (s_code != e_code); /* only put blank after comma * if comma does not start the * line */ if (ps.in_decl && ps.procname[0] == '\0' && !ps.block_init && !ps.dumped_decl_indent && ps.paren_level == 0) { /* indent leading commas and not the actual identifiers */ indent_declaration(dec_ind - 1, tabs_to_var); ps.dumped_decl_indent = true; } *e_code++ = ','; if (ps.p_l_follow == 0) { if (ps.block_init_level <= 0) ps.block_init = 0; - if (break_comma && (!ps.leave_comma || + if (break_comma && (!opt.leave_comma || count_spaces_until(compute_code_target(), s_code, e_code) > - max_col - tabsize)) + opt.max_col - opt.tabsize)) force_nl = true; } break; case preesc: /* got the character '#' */ if ((s_com != e_com) || (s_lab != e_lab) || (s_code != e_code)) dump_line(); CHECK_SIZE_LAB(1); *e_lab++ = '#'; /* move whole line to 'label' buffer */ { int in_comment = 0; int com_start = 0; char quote = 0; int com_end = 0; while (*buf_ptr == ' ' || *buf_ptr == '\t') { buf_ptr++; if (buf_ptr >= buf_end) fill_buffer(); } while (*buf_ptr != '\n' || (in_comment && !had_eof)) { CHECK_SIZE_LAB(2); *e_lab = *buf_ptr++; if (buf_ptr >= buf_end) fill_buffer(); switch (*e_lab++) { case BACKSLASH: if (!in_comment) { *e_lab++ = *buf_ptr++; if (buf_ptr >= buf_end) fill_buffer(); } break; case '/': if (*buf_ptr == '*' && !in_comment && !quote) { in_comment = 1; *e_lab++ = *buf_ptr++; com_start = e_lab - s_lab - 2; } break; case '"': if (quote == '"') quote = 0; break; case '\'': if (quote == '\'') quote = 0; break; case '*': if (*buf_ptr == '/' && in_comment) { in_comment = 0; *e_lab++ = *buf_ptr++; com_end = e_lab - s_lab; } break; } } while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) e_lab--; if (e_lab - s_lab == com_end && bp_save == NULL) { /* comment on preprocessor line */ if (sc_end == NULL) { /* if this is the first comment, * we must set up the buffer */ save_com = sc_buf; sc_end = &save_com[0]; } else { *sc_end++ = '\n'; /* add newline between * comments */ *sc_end++ = ' '; --line_no; } if (sc_end - save_com + com_end - com_start > sc_size) errx(1, "input too long"); memmove(sc_end, s_lab + com_start, com_end - com_start); sc_end += com_end - com_start; e_lab = s_lab + com_start; while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) e_lab--; bp_save = buf_ptr; /* save current input buffer */ be_save = buf_end; buf_ptr = save_com; /* fix so that subsequent calls to * lexi will take tokens out of * save_com */ *sc_end++ = ' '; /* add trailing blank, just in case */ buf_end = sc_end; sc_end = NULL; } CHECK_SIZE_LAB(1); *e_lab = '\0'; /* null terminate line */ ps.pcase = false; } if (strncmp(s_lab, "#if", 3) == 0) { /* also ifdef, ifndef */ if ((size_t)ifdef_level < nitems(state_stack)) { match_state[ifdef_level].tos = -1; state_stack[ifdef_level++] = ps; } else diag2(1, "#if stack overflow"); } else if (strncmp(s_lab, "#el", 3) == 0) { /* else, elif */ if (ifdef_level <= 0) diag2(1, s_lab[3] == 'i' ? "Unmatched #elif" : "Unmatched #else"); else { match_state[ifdef_level - 1] = ps; ps = state_stack[ifdef_level - 1]; } } else if (strncmp(s_lab, "#endif", 6) == 0) { if (ifdef_level <= 0) diag2(1, "Unmatched #endif"); else ifdef_level--; } else { struct directives { int size; const char *string; } recognized[] = { {7, "include"}, {6, "define"}, {5, "undef"}, {4, "line"}, {5, "error"}, {6, "pragma"} }; int d = nitems(recognized); while (--d >= 0) if (strncmp(s_lab + 1, recognized[d].string, recognized[d].size) == 0) break; if (d < 0) { diag2(1, "Unrecognized cpp directive"); break; } } - if (blanklines_around_conditional_compilation) { + if (opt.blanklines_around_conditional_compilation) { postfix_blankline_requested++; n_real_blanklines = 0; } else { postfix_blankline_requested = 0; prefix_blankline_requested = 0; } break; /* subsequent processing of the newline * character will cause the line to be printed */ case comment: /* we have gotten a / followed by * this is a biggie */ pr_comment(); break; } /* end of big switch stmt */ *e_code = '\0'; /* make sure code section is null terminated */ if (type_code != comment && type_code != newline && type_code != preesc) ps.last_token = type_code; } /* end of main while (1) loop */ } /* * copy input file to backup file if in_name is /blah/blah/blah/file, then * backup file will be ".Bfile" then make the backup file the input and * original input file the output */ static void bakcopy(void) { int n, bakchn; char buff[8 * 1024]; const char *p; /* construct file name .Bfile */ for (p = in_name; *p; p++); /* skip to end of string */ while (p > in_name && *p != '/') /* find last '/' */ p--; if (*p == '/') p++; sprintf(bakfile, "%s%s", p, simple_backup_suffix); /* copy in_name to backup file */ bakchn = creat(bakfile, 0600); if (bakchn < 0) err(1, "%s", bakfile); while ((n = read(fileno(input), buff, sizeof(buff))) > 0) if (write(bakchn, buff, n) != n) err(1, "%s", bakfile); if (n < 0) err(1, "%s", in_name); close(bakchn); fclose(input); /* re-open backup file as the input file */ input = fopen(bakfile, "r"); if (input == NULL) err(1, "%s", bakfile); /* now the original input file will be the output */ output = fopen(in_name, "w"); if (output == NULL) { unlink(bakfile); err(1, "%s", in_name); } } static void indent_declaration(int cur_dec_ind, int tabs_to_var) { int pos = e_code - s_code; char *startpos = e_code; /* * get the tab math right for indentations that are not multiples of tabsize */ - if ((ps.ind_level * ps.ind_size) % tabsize != 0) { - pos += (ps.ind_level * ps.ind_size) % tabsize; - cur_dec_ind += (ps.ind_level * ps.ind_size) % tabsize; + if ((ps.ind_level * opt.ind_size) % opt.tabsize != 0) { + pos += (ps.ind_level * opt.ind_size) % opt.tabsize; + cur_dec_ind += (ps.ind_level * opt.ind_size) % opt.tabsize; } if (tabs_to_var) { int tpos; - CHECK_SIZE_CODE(cur_dec_ind / tabsize); - while ((tpos = tabsize * (1 + pos / tabsize)) <= cur_dec_ind) { + CHECK_SIZE_CODE(cur_dec_ind / opt.tabsize); + while ((tpos = opt.tabsize * (1 + pos / opt.tabsize)) <= cur_dec_ind) { *e_code++ = '\t'; pos = tpos; } } CHECK_SIZE_CODE(cur_dec_ind - pos + 1); while (pos < cur_dec_ind) { *e_code++ = ' '; pos++; } if (e_code == startpos && ps.want_blank) { *e_code++ = ' '; ps.want_blank = false; } } Index: head/usr.bin/indent/indent_globs.h =================================================================== --- head/usr.bin/indent/indent_globs.h (revision 334926) +++ head/usr.bin/indent/indent_globs.h (revision 334927) @@ -1,322 +1,317 @@ /*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright (c) 1985 Sun Microsystems, Inc. * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)indent_globs.h 8.1 (Berkeley) 6/6/93 * $FreeBSD$ */ #define BACKSLASH '\\' #define bufsize 200 /* size of internal buffers */ #define sc_size 5000 /* size of save_com buffer */ #define label_offset 2 /* number of levels a label is placed to left * of code */ #define false 0 #define true 1 FILE *input; /* the fid for the input file */ FILE *output; /* the output file */ #define CHECK_SIZE_CODE(desired_size) \ if (e_code + (desired_size) >= l_code) { \ int nsize = l_code-s_code + 400 + desired_size; \ int code_len = e_code-s_code; \ codebuf = (char *) realloc(codebuf, nsize); \ if (codebuf == NULL) \ err(1, NULL); \ e_code = codebuf + code_len + 1; \ l_code = codebuf + nsize - 5; \ s_code = codebuf + 1; \ } #define CHECK_SIZE_COM(desired_size) \ if (e_com + (desired_size) >= l_com) { \ int nsize = l_com-s_com + 400 + desired_size; \ int com_len = e_com - s_com; \ int blank_pos; \ if (last_bl != NULL) \ blank_pos = last_bl - combuf; \ else \ blank_pos = -1; \ combuf = (char *) realloc(combuf, nsize); \ if (combuf == NULL) \ err(1, NULL); \ e_com = combuf + com_len + 1; \ if (blank_pos > 0) \ last_bl = combuf + blank_pos; \ l_com = combuf + nsize - 5; \ s_com = combuf + 1; \ } #define CHECK_SIZE_LAB(desired_size) \ if (e_lab + (desired_size) >= l_lab) { \ int nsize = l_lab-s_lab + 400 + desired_size; \ int label_len = e_lab - s_lab; \ labbuf = (char *) realloc(labbuf, nsize); \ if (labbuf == NULL) \ err(1, NULL); \ e_lab = labbuf + label_len + 1; \ l_lab = labbuf + nsize - 5; \ s_lab = labbuf + 1; \ } #define CHECK_SIZE_TOKEN(desired_size) \ if (e_token + (desired_size) >= l_token) { \ int nsize = l_token-s_token + 400 + desired_size; \ int token_len = e_token - s_token; \ tokenbuf = (char *) realloc(tokenbuf, nsize); \ if (tokenbuf == NULL) \ err(1, NULL); \ e_token = tokenbuf + token_len + 1; \ l_token = tokenbuf + nsize - 5; \ s_token = tokenbuf + 1; \ } char *labbuf; /* buffer for label */ char *s_lab; /* start ... */ char *e_lab; /* .. and end of stored label */ char *l_lab; /* limit of label buffer */ char *codebuf; /* buffer for code section */ char *s_code; /* start ... */ char *e_code; /* .. and end of stored code */ char *l_code; /* limit of code section */ char *combuf; /* buffer for comments */ char *s_com; /* start ... */ char *e_com; /* ... and end of stored comments */ char *l_com; /* limit of comment buffer */ #define token s_token char *tokenbuf; /* the last token scanned */ char *s_token; char *e_token; char *l_token; char *in_buffer; /* input buffer */ char *in_buffer_limit; /* the end of the input buffer */ char *buf_ptr; /* ptr to next character to be taken from * in_buffer */ char *buf_end; /* ptr to first after last char in in_buffer */ char sc_buf[sc_size]; /* input text is saved here when looking for * the brace after an if, while, etc */ char *save_com; /* start of the comment stored in sc_buf */ char *sc_end; /* pointer into save_com buffer */ char *bp_save; /* saved value of buf_ptr when taking input * from save_com */ char *be_save; /* similarly saved value of buf_end */ +struct options { + int blanklines_around_conditional_compilation; + int blanklines_after_declarations_at_proctop; /* this is vaguely + * similar to blanklines_after_decla except + * that in only applies to the first set of + * declarations in a procedure (just after + * the first '{') and it causes a blank line + * to be generated even if there are no + * declarations */ + int blanklines_after_declarations; + int blanklines_after_procs; + int blanklines_before_blockcomments; + int leave_comma; /* if true, never break declarations after + * commas */ + int btype_2; /* when true, brace should be on same line + * as if, while, etc */ + int Bill_Shannon; /* true iff a blank should always be + * inserted after sizeof */ + int comment_delimiter_on_blankline; + int decl_com_ind; /* the column in which comments after + * declarations should be put */ + int cuddle_else; /* true if else should cuddle up to '}' */ + int continuation_indent; /* set to the indentation between the + * edge of code and continuation lines */ + int com_ind; /* the column in which comments to the right + * of code should start */ + int decl_indent; /* column to indent declared identifiers to */ + int ljust_decl; /* true if declarations should be left + * justified */ + int unindent_displace; /* comments not to the right of code + * will be placed this many + * indentation levels to the left of + * code */ + int extra_expression_indent; /* true if continuation lines from + * the expression part of "if(e)", + * "while(e)", "for(e;e;e)" should be + * indented an extra tab stop so that they + * don't conflict with the code that follows */ + int else_if; /* True iff else if pairs should be handled + * specially */ + int function_brace_split; /* split function declaration and + * brace onto separate lines */ + int format_col1_comments; /* If comments which start in column 1 + * are to be magically reformatted (just + * like comments that begin in later columns) */ + int format_block_comments; /* true if comments beginning with + * `/ * \n' are to be reformatted */ + int indent_parameters; + int ind_size; /* the size of one indentation level */ + int block_comment_max_col; + int local_decl_indent; /* like decl_indent but for locals */ + int lineup_to_parens_always; /* if true, do not attempt to keep + * lined-up code within the margin */ + int lineup_to_parens; /* if true, continued code within parens + * will be lined up to the open paren */ + int proc_calls_space; /* If true, procedure calls look like: + * foo (bar) rather than foo(bar) */ + int procnames_start_line; /* if true, the names of procedures + * being defined get placed in column 1 (ie. + * a newline is placed between the type of + * the procedure and its name) */ + int space_after_cast; /* "b = (int) a" vs "b = (int)a" */ + int star_comment_cont; /* true iff comment continuation lines + * should have stars at the beginning of + * each line. */ + int swallow_optional_blanklines; + int auto_typedefs; /* set true to recognize identifiers + * ending in "_t" like typedefs */ + int tabsize; /* the size of a tab */ + int max_col; /* the maximum allowable line length */ + int use_tabs; /* set true to use tabs for spacing, false + * uses all spaces */ + int verbose; /* when true, non-essential error messages + * are printed */ +} opt; + int found_err; -int blanklines_after_declarations; -int blanklines_before_blockcomments; -int blanklines_after_procs; -int blanklines_around_conditional_compilation; -int swallow_optional_blanklines; int n_real_blanklines; int prefix_blankline_requested; int postfix_blankline_requested; int break_comma; /* when true and not in parens, break after a * comma */ -int btype_2; /* when true, brace should be on same line as - * if, while, etc */ float case_ind; /* indentation level to be used for a "case * n:" */ int code_lines; /* count of lines with code */ int had_eof; /* set to true when input is exhausted */ int line_no; /* the current line number. */ -int max_col; /* the maximum allowable line length */ -int verbose; /* when true, non-essential error messages are - * printed */ -int cuddle_else; /* true if else should cuddle up to '}' */ -int star_comment_cont; /* true iff comment continuation lines should - * have stars at the beginning of each line. */ -int comment_delimiter_on_blankline; -int procnames_start_line; /* if true, the names of procedures - * being defined get placed in column - * 1 (ie. a newline is placed between - * the type of the procedure and its - * name) */ -int proc_calls_space; /* If true, procedure calls look like: - * foo (bar) rather than foo(bar) */ -int format_block_comments; /* true if comments beginning with - * `/ * \n' are to be reformatted */ -int format_col1_comments; /* If comments which start in column 1 - * are to be magically reformatted - * (just like comments that begin in - * later columns) */ int inhibit_formatting; /* true if INDENT OFF is in effect */ int suppress_blanklines;/* set iff following blanklines should be * suppressed */ -int continuation_indent;/* set to the indentation between the edge of - * code and continuation lines */ -int lineup_to_parens; /* if true, continued code within parens will - * be lined up to the open paren */ -int lineup_to_parens_always; /* if true, do not attempt to keep - * lined-up code within the margin */ -int Bill_Shannon; /* true iff a blank should always be inserted - * after sizeof */ -int blanklines_after_declarations_at_proctop; /* This is vaguely - * similar to - * blanklines_after_decla - * rations except that - * it only applies to - * the first set of - * declarations in a - * procedure (just after - * the first '{') and it - * causes a blank line - * to be generated even - * if there are no - * declarations */ -int block_comment_max_col; -int extra_expression_indent; /* true if continuation lines from the - * expression part of "if(e)", - * "while(e)", "for(e;e;e)" should be - * indented an extra tab stop so that - * they don't conflict with the code - * that follows */ -int function_brace_split; /* split function declaration and - * brace onto separate lines */ -int use_tabs; /* set true to use tabs for spacing, - * false uses all spaces */ -int auto_typedefs; /* set true to recognize identifiers - * ending in "_t" like typedefs */ -int space_after_cast; /* "b = (int) a" vs "b = (int)a" */ -int tabsize; /* the size of a tab */ struct parser_state { int last_token; int p_stack[256]; /* this is the parsers stack */ int il[64]; /* this stack stores indentation levels */ float cstk[32]; /* used to store case stmt indentation levels */ int box_com; /* set to true when we are in a "boxed" * comment. In that case, the first non-blank * char should be lined up with the / in / followed by * */ int comment_delta; /* used to set up indentation for all lines * of a boxed comment after the first one */ int n_comment_delta;/* remembers how many columns there were * before the start of a box comment so that * forthcoming lines of the comment are * indented properly */ int cast_mask; /* indicates which close parens potentially * close off casts */ int not_cast_mask; /* indicates which close parens definitely * close off something else than casts */ int block_init; /* true iff inside a block initialization */ int block_init_level; /* The level of brace nesting in an * initialization */ int last_nl; /* this is true if the last thing scanned was * a newline */ int in_or_st; /* Will be true iff there has been a * declarator (e.g. int or char) and no left * paren since the last semicolon. When true, * a '{' is starting a structure definition or * an initialization list */ int bl_line; /* set to 1 by dump_line if the line is blank */ int col_1; /* set to true if the last token started in * column 1 */ int com_col; /* this is the column in which the current * comment should start */ - int com_ind; /* the column in which comments to the right - * of code should start */ int com_lines; /* the number of lines with comments, set by * dump_line */ int dec_nest; /* current nesting level for structure or init */ - int decl_com_ind; /* the column in which comments after - * declarations should be put */ int decl_on_line; /* set to true if this line of code has part * of a declaration on it */ int i_l_follow; /* the level to which ind_level should be set * after the current line is printed */ int in_decl; /* set to true when we are in a declaration * stmt. The processing of braces is then * slightly different */ int in_stmt; /* set to 1 while in a stmt */ int ind_level; /* the current indentation level */ - int ind_size; /* the size of one indentation level */ int ind_stmt; /* set to 1 if next line should have an extra * indentation level because we are in the * middle of a stmt */ int last_u_d; /* set to true after scanning a token which * forces a following operator to be unary */ - int leave_comma; /* if true, never break declarations after - * commas */ - int ljust_decl; /* true if declarations should be left - * justified */ int out_coms; /* the number of comments processed, set by * pr_comment */ int out_lines; /* the number of lines written, set by * dump_line */ int p_l_follow; /* used to remember how to indent following * statement */ int paren_level; /* parenthesization level. used to indent * within statements */ short paren_indents[20]; /* column positions of each paren */ int pcase; /* set to 1 if the current line label is a * case. It is printed differently from a * regular label */ int search_brace; /* set to true by parse when it is necessary * to buffer up all info up to the start of a * stmt after an if, while, etc */ - int unindent_displace; /* comments not to the right of code - * will be placed this many - * indentation levels to the left of - * code */ int use_ff; /* set to one if the current line should be * terminated with a form feed */ int want_blank; /* set to true when the following token should * be prefixed by a blank. (Said prefixing is * ignored in some cases.) */ - int else_if; /* True iff else if pairs should be handled - * specially */ - int decl_indent; /* column to indent declared identifiers to */ - int local_decl_indent; /* like decl_indent but for locals */ int keyword; /* the type of a keyword or 0 */ int dumped_decl_indent; float case_indent; /* The distance to indent case labels from the * switch statement */ int in_parameter_declaration; - int indent_parameters; int tos; /* pointer to top of stack */ char procname[100]; /* The name of the current procedure */ int just_saw_decl; } ps; int ifdef_level; struct parser_state state_stack[5]; struct parser_state match_state[5]; Index: head/usr.bin/indent/io.c =================================================================== --- head/usr.bin/indent/io.c (revision 334926) +++ head/usr.bin/indent/io.c (revision 334927) @@ -1,526 +1,528 @@ /*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright (c) 1985 Sun Microsystems, Inc. * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if 0 #ifndef lint static char sccsid[] = "@(#)io.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ #endif #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include "indent_globs.h" #include "indent.h" int comment_open; static int paren_target; static int pad_output(int current, int target); void dump_line(void) { /* dump_line is the routine that actually * effects the printing of the new source. It * prints the label section, followed by the * code section with the appropriate nesting * level, followed by any comments */ int cur_col, target_col = 1; static int not_first_line; if (ps.procname[0]) { ps.ind_level = 0; ps.procname[0] = 0; } if (s_code == e_code && s_lab == e_lab && s_com == e_com) { if (suppress_blanklines > 0) suppress_blanklines--; else { ps.bl_line = true; n_real_blanklines++; } } else if (!inhibit_formatting) { suppress_blanklines = 0; ps.bl_line = false; if (prefix_blankline_requested && not_first_line) { - if (swallow_optional_blanklines) { + if (opt.swallow_optional_blanklines) { if (n_real_blanklines == 1) n_real_blanklines = 0; } else { if (n_real_blanklines == 0) n_real_blanklines = 1; } } while (--n_real_blanklines >= 0) putc('\n', output); n_real_blanklines = 0; if (ps.ind_level == 0) ps.ind_stmt = 0; /* this is a class A kludge. dont do * additional statement indentation if we are * at bracket level 0 */ if (e_lab != s_lab || e_code != s_code) ++code_lines; /* keep count of lines with code */ if (e_lab != s_lab) { /* print lab, if any */ if (comment_open) { comment_open = 0; fprintf(output, ".*/\n"); } while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) e_lab--; *e_lab = '\0'; cur_col = pad_output(1, compute_label_target()); if (s_lab[0] == '#' && (strncmp(s_lab, "#else", 5) == 0 || strncmp(s_lab, "#endif", 6) == 0)) { char *s = s_lab; if (e_lab[-1] == '\n') e_lab--; do putc(*s++, output); while (s < e_lab && 'a' <= *s && *s<='z'); while ((*s == ' ' || *s == '\t') && s < e_lab) s++; if (s < e_lab) fprintf(output, s[0]=='/' && s[1]=='*' ? "\t%.*s" : "\t/* %.*s */", (int)(e_lab - s), s); } else fprintf(output, "%.*s", (int)(e_lab - s_lab), s_lab); cur_col = count_spaces(cur_col, s_lab); } else cur_col = 1; /* there is no label section */ ps.pcase = false; if (s_code != e_code) { /* print code section, if any */ char *p; if (comment_open) { comment_open = 0; fprintf(output, ".*/\n"); } target_col = compute_code_target(); { int i; for (i = 0; i < ps.p_l_follow; i++) if (ps.paren_indents[i] >= 0) ps.paren_indents[i] = -(ps.paren_indents[i] + target_col); } cur_col = pad_output(cur_col, target_col); for (p = s_code; p < e_code; p++) if (*p == (char) 0200) fprintf(output, "%d", target_col * 7); else putc(*p, output); cur_col = count_spaces(cur_col, s_code); } if (s_com != e_com) { /* print comment, if any */ int target = ps.com_col; char *com_st = s_com; target += ps.comment_delta; while (*com_st == '\t') /* consider original indentation in * case this is a box comment */ - com_st++, target += tabsize; + com_st++, target += opt.tabsize; while (target <= 0) if (*com_st == ' ') target++, com_st++; - else if (*com_st == '\t') - target = tabsize * (1 + (target - 1) / tabsize) + 1, com_st++; + else if (*com_st == '\t') { + target = opt.tabsize * (1 + (target - 1) / opt.tabsize) + 1; + com_st++; + } else target = 1; if (cur_col > target) { /* if comment can't fit on this line, * put it on next line */ putc('\n', output); cur_col = 1; ++ps.out_lines; } while (e_com > com_st && isspace((unsigned char)e_com[-1])) e_com--; (void)pad_output(cur_col, target); fwrite(com_st, e_com - com_st, 1, output); ps.comment_delta = ps.n_comment_delta; ++ps.com_lines; /* count lines with comments */ } if (ps.use_ff) putc('\014', output); else putc('\n', output); ++ps.out_lines; - if (ps.just_saw_decl == 1 && blanklines_after_declarations) { + if (ps.just_saw_decl == 1 && opt.blanklines_after_declarations) { prefix_blankline_requested = 1; ps.just_saw_decl = 0; } else prefix_blankline_requested = postfix_blankline_requested; postfix_blankline_requested = 0; } ps.decl_on_line = ps.in_decl; /* if we are in the middle of a * declaration, remember that fact for * proper comment indentation */ ps.ind_stmt = ps.in_stmt & ~ps.in_decl; /* next line should be * indented if we have not * completed this stmt and if * we are not in the middle of * a declaration */ ps.use_ff = false; ps.dumped_decl_indent = 0; *(e_lab = s_lab) = '\0'; /* reset buffers */ *(e_code = s_code) = '\0'; *(e_com = s_com = combuf + 1) = '\0'; ps.ind_level = ps.i_l_follow; ps.paren_level = ps.p_l_follow; if (ps.paren_level > 0) paren_target = -ps.paren_indents[ps.paren_level - 1]; not_first_line = 1; } int compute_code_target(void) { - int target_col = ps.ind_size * ps.ind_level + 1; + int target_col = opt.ind_size * ps.ind_level + 1; if (ps.paren_level) - if (!lineup_to_parens) - target_col += continuation_indent - * (2 * continuation_indent == ps.ind_size ? 1 : ps.paren_level); - else if (lineup_to_parens_always) + if (!opt.lineup_to_parens) + target_col += opt.continuation_indent * + (2 * opt.continuation_indent == opt.ind_size ? 1 : ps.paren_level); + else if (opt.lineup_to_parens_always) target_col = paren_target; else { int w; int t = paren_target; - if ((w = count_spaces(t, s_code) - max_col) > 0 - && count_spaces(target_col, s_code) <= max_col) { + if ((w = count_spaces(t, s_code) - opt.max_col) > 0 + && count_spaces(target_col, s_code) <= opt.max_col) { t -= w + 1; if (t > target_col) target_col = t; } else target_col = t; } else if (ps.ind_stmt) - target_col += continuation_indent; + target_col += opt.continuation_indent; return target_col; } int compute_label_target(void) { return - ps.pcase ? (int) (case_ind * ps.ind_size) + 1 + ps.pcase ? (int) (case_ind * opt.ind_size) + 1 : *s_lab == '#' ? 1 - : ps.ind_size * (ps.ind_level - label_offset) + 1; + : opt.ind_size * (ps.ind_level - label_offset) + 1; } /* * Copyright (C) 1976 by the Board of Trustees of the University of Illinois * * All rights reserved * * * NAME: fill_buffer * * FUNCTION: Reads one block of input into input_buffer * * HISTORY: initial coding November 1976 D A Willcox of CAC 1/7/77 A * Willcox of CAC Added check for switch back to partly full input * buffer from temporary buffer * */ void fill_buffer(void) { /* this routine reads stuff from the input */ char *p; int i; FILE *f = input; if (bp_save != NULL) { /* there is a partly filled input buffer left */ buf_ptr = bp_save; /* do not read anything, just switch buffers */ buf_end = be_save; bp_save = be_save = NULL; if (buf_ptr < buf_end) return; /* only return if there is really something in * this buffer */ } for (p = in_buffer;;) { if (p >= in_buffer_limit) { int size = (in_buffer_limit - in_buffer) * 2 + 10; int offset = p - in_buffer; in_buffer = realloc(in_buffer, size); if (in_buffer == NULL) errx(1, "input line too long"); p = in_buffer + offset; in_buffer_limit = in_buffer + size - 2; } if ((i = getc(f)) == EOF) { *p++ = ' '; *p++ = '\n'; had_eof = true; break; } if (i != '\0') *p++ = i; if (i == '\n') break; } buf_ptr = in_buffer; buf_end = p; if (p - in_buffer > 2 && p[-2] == '/' && p[-3] == '*') { if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0) fill_buffer(); /* flush indent error message */ else { int com = 0; p = in_buffer; while (*p == ' ' || *p == '\t') p++; if (*p == '/' && p[1] == '*') { p += 2; while (*p == ' ' || *p == '\t') p++; if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E' && p[4] == 'N' && p[5] == 'T') { p += 6; while (*p == ' ' || *p == '\t') p++; if (*p == '*') com = 1; else if (*p == 'O') { if (*++p == 'N') p++, com = 1; else if (*p == 'F' && *++p == 'F') p++, com = 2; } while (*p == ' ' || *p == '\t') p++; if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com) { if (s_com != e_com || s_lab != e_lab || s_code != e_code) dump_line(); if (!(inhibit_formatting = com - 1)) { n_real_blanklines = 0; postfix_blankline_requested = 0; prefix_blankline_requested = 0; suppress_blanklines = 1; } } } } } } if (inhibit_formatting) { p = in_buffer; do putc(*p, output); while (*p++ != '\n'); } } /* * Copyright (C) 1976 by the Board of Trustees of the University of Illinois * * All rights reserved * * * NAME: pad_output * * FUNCTION: Writes tabs and spaces to move the current column up to the desired * position. * * ALGORITHM: Put tabs and/or blanks into pobuf, then write pobuf. * * PARAMETERS: current integer The current column target * nteger The desired column * * RETURNS: Integer value of the new column. (If current >= target, no action is * taken, and current is returned. * * GLOBALS: None * * CALLS: write (sys) * * CALLED BY: dump_line * * HISTORY: initial coding November 1976 D A Willcox of CAC * */ static int pad_output(int current, int target) /* writes tabs and blanks (if necessary) to * get the current output position up to the * target column */ /* current: the current column value */ /* target: position we want it at */ { int curr; /* internal column pointer */ if (current >= target) return (current); /* line is already long enough */ curr = current; - if (use_tabs) { + if (opt.use_tabs) { int tcur; - while ((tcur = tabsize * (1 + (curr - 1) / tabsize) + 1) <= target) { + while ((tcur = opt.tabsize * (1 + (curr - 1) / opt.tabsize) + 1) <= target) { putc('\t', output); curr = tcur; } } while (curr++ < target) putc(' ', output); /* pad with final blanks */ return (target); } /* * Copyright (C) 1976 by the Board of Trustees of the University of Illinois * * All rights reserved * * * NAME: count_spaces * * FUNCTION: Find out where printing of a given string will leave the current * character position on output. * * ALGORITHM: Run thru input string and add appropriate values to current * position. * * RETURNS: Integer value of position after printing "buffer" starting in column * "current". * * HISTORY: initial coding November 1976 D A Willcox of CAC * */ int count_spaces_until(int cur, char *buffer, char *end) /* * this routine figures out where the character position will be after * printing the text in buffer starting at column "current" */ { char *buf; /* used to look thru buffer */ for (buf = buffer; *buf != '\0' && buf != end; ++buf) { switch (*buf) { case '\n': case 014: /* form feed */ cur = 1; break; case '\t': - cur = tabsize * (1 + (cur - 1) / tabsize) + 1; + cur = opt.tabsize * (1 + (cur - 1) / opt.tabsize) + 1; break; case 010: /* backspace */ --cur; break; default: ++cur; break; } /* end of switch */ } /* end of for loop */ return (cur); } int count_spaces(int cur, char *buffer) { return (count_spaces_until(cur, buffer, NULL)); } void diag4(int level, const char *msg, int a, int b) { if (level) found_err = 1; if (output == stdout) { fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no); fprintf(stdout, msg, a, b); fprintf(stdout, " */\n"); } else { fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no); fprintf(stderr, msg, a, b); fprintf(stderr, "\n"); } } void diag3(int level, const char *msg, int a) { if (level) found_err = 1; if (output == stdout) { fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no); fprintf(stdout, msg, a); fprintf(stdout, " */\n"); } else { fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no); fprintf(stderr, msg, a); fprintf(stderr, "\n"); } } void diag2(int level, const char *msg) { if (level) found_err = 1; if (output == stdout) { fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no); fprintf(stdout, "%s", msg); fprintf(stdout, " */\n"); } else { fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no); fprintf(stderr, "%s", msg); fprintf(stderr, "\n"); } } Index: head/usr.bin/indent/lexi.c =================================================================== --- head/usr.bin/indent/lexi.c (revision 334926) +++ head/usr.bin/indent/lexi.c (revision 334927) @@ -1,672 +1,672 @@ /*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright (c) 1985 Sun Microsystems, Inc. * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if 0 #ifndef lint static char sccsid[] = "@(#)lexi.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ #endif #include __FBSDID("$FreeBSD$"); /* * Here we have the token scanner for indent. It scans off one token and puts * it in the global variable "token". It returns a code, indicating the type * of token scanned. */ #include #include #include #include #include #include "indent_globs.h" #include "indent_codes.h" #include "indent.h" #define alphanum 1 #ifdef undef #define opchar 3 #endif struct templ { const char *rwd; int rwcode; }; /* * This table has to be sorted alphabetically, because it'll be used in binary * search. For the same reason, string must be the first thing in struct templ. */ struct templ specials[] = { {"_Bool", 4}, {"_Complex", 4}, {"_Imaginary", 4}, {"auto", 10}, {"bool", 4}, {"break", 9}, {"case", 8}, {"char", 4}, {"complex", 4}, {"const", 4}, {"continue", 12}, {"default", 8}, {"do", 6}, {"double", 4}, {"else", 6}, {"enum", 3}, {"extern", 10}, {"float", 4}, {"for", 5}, {"global", 4}, {"goto", 9}, {"if", 5}, {"imaginary", 4}, {"inline", 12}, {"int", 4}, {"long", 4}, {"offsetof", 1}, {"register", 10}, {"restrict", 12}, {"return", 9}, {"short", 4}, {"signed", 4}, {"sizeof", 2}, {"static", 10}, {"struct", 3}, {"switch", 7}, {"typedef", 11}, {"union", 3}, {"unsigned", 4}, {"void", 4}, {"volatile", 4}, {"while", 5} }; const char **typenames; int typename_count; int typename_top = -1; char chartype[128] = { /* this is used to facilitate the decision of * what type (alphanumeric, operator) each * character is */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 3, 3, 0, 0, 0, 3, 3, 0, 3, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 3, 3, 3, 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 3, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 3, 0, 3, 0 }; static int strcmp_type(const void *e1, const void *e2) { return (strcmp(e1, *(const char * const *)e2)); } int lexi(struct parser_state *state) { int unary_delim; /* this is set to 1 if the current token * forces a following operator to be unary */ int code; /* internal code to be returned */ char qchar; /* the delimiter character for a string */ e_token = s_token; /* point to start of place to save token */ unary_delim = false; state->col_1 = state->last_nl; /* tell world that this token started * in column 1 iff the last thing * scanned was a newline */ state->last_nl = false; while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */ state->col_1 = false; /* leading blanks imply token is not in column * 1 */ if (++buf_ptr >= buf_end) fill_buffer(); } /* Scan an alphanumeric token */ if (chartype[*buf_ptr & 127] == alphanum || (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) { /* * we have a character or number */ struct templ *p; if (isdigit((unsigned char)*buf_ptr) || (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) { int seendot = 0, seenexp = 0, seensfx = 0; /* * base 2, base 8, base 16: */ if (buf_ptr[0] == '0' && buf_ptr[1] != '.') { int len; if (buf_ptr[1] == 'b' || buf_ptr[1] == 'B') len = strspn(buf_ptr + 2, "01") + 2; else if (buf_ptr[1] == 'x' || buf_ptr[1] == 'X') len = strspn(buf_ptr + 2, "0123456789ABCDEFabcdef") + 2; else len = strspn(buf_ptr + 1, "012345678") + 1; if (len > 0) { CHECK_SIZE_TOKEN(len); memcpy(e_token, buf_ptr, len); e_token += len; buf_ptr += len; } else diag2(1, "Unterminated literal"); } else /* base 10: */ while (1) { if (*buf_ptr == '.') { if (seendot) break; else seendot++; } CHECK_SIZE_TOKEN(3); *e_token++ = *buf_ptr++; if (!isdigit((unsigned char)*buf_ptr) && *buf_ptr != '.') { if ((*buf_ptr != 'E' && *buf_ptr != 'e') || seenexp) break; else { seenexp++; seendot++; *e_token++ = *buf_ptr++; if (*buf_ptr == '+' || *buf_ptr == '-') *e_token++ = *buf_ptr++; } } } while (1) { CHECK_SIZE_TOKEN(2); if (!(seensfx & 1) && (*buf_ptr == 'U' || *buf_ptr == 'u')) { *e_token++ = *buf_ptr++; seensfx |= 1; continue; } if (!(seensfx & 2) && (strchr("fFlL", *buf_ptr) != NULL)) { if (buf_ptr[1] == buf_ptr[0]) *e_token++ = *buf_ptr++; *e_token++ = *buf_ptr++; seensfx |= 2; continue; } break; } } else while (chartype[*buf_ptr & 127] == alphanum || *buf_ptr == BACKSLASH) { /* fill_buffer() terminates buffer with newline */ if (*buf_ptr == BACKSLASH) { if (*(buf_ptr + 1) == '\n') { buf_ptr += 2; if (buf_ptr >= buf_end) fill_buffer(); } else break; } CHECK_SIZE_TOKEN(1); /* copy it over */ *e_token++ = *buf_ptr++; if (buf_ptr >= buf_end) fill_buffer(); } *e_token = '\0'; if (s_token[0] == 'L' && s_token[1] == '\0' && (*buf_ptr == '"' || *buf_ptr == '\'')) return (strpfx); while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */ if (++buf_ptr >= buf_end) fill_buffer(); } state->keyword = 0; if (state->last_token == structure && !state->p_l_follow) { /* if last token was 'struct' and we're not * in parentheses, then this token * should be treated as a declaration */ state->last_u_d = true; return (decl); } /* * Operator after identifier is binary unless last token was 'struct' */ state->last_u_d = (state->last_token == structure); p = bsearch(s_token, specials, sizeof(specials) / sizeof(specials[0]), sizeof(specials[0]), strcmp_type); if (p == NULL) { /* not a special keyword... */ char *u; /* ... so maybe a type_t or a typedef */ - if ((auto_typedefs && ((u = strrchr(s_token, '_')) != NULL) && + if ((opt.auto_typedefs && ((u = strrchr(s_token, '_')) != NULL) && strcmp(u, "_t") == 0) || (typename_top >= 0 && bsearch(s_token, typenames, typename_top + 1, sizeof(typenames[0]), strcmp_type))) { state->keyword = 4; /* a type name */ state->last_u_d = true; goto found_typename; } } else { /* we have a keyword */ state->keyword = p->rwcode; state->last_u_d = true; switch (p->rwcode) { case 7: /* it is a switch */ return (swstmt); case 8: /* a case or default */ return (casestmt); case 3: /* a "struct" */ /* FALLTHROUGH */ case 4: /* one of the declaration keywords */ found_typename: if (state->p_l_follow) { /* inside parens: cast, param list, offsetof or sizeof */ state->cast_mask |= (1 << state->p_l_follow) & ~state->not_cast_mask; } if (state->last_token == period || state->last_token == unary_op) { state->keyword = 0; break; } if (p != NULL && p->rwcode == 3) return (structure); if (state->p_l_follow) break; return (decl); case 5: /* if, while, for */ return (sp_paren); case 6: /* do, else */ return (sp_nparen); case 10: /* storage class specifier */ return (storage); case 11: /* typedef */ return (type_def); default: /* all others are treated like any other * identifier */ return (ident); } /* end of switch */ } /* end of if (found_it) */ if (*buf_ptr == '(' && state->tos <= 1 && state->ind_level == 0 && state->in_parameter_declaration == 0 && state->block_init == 0) { char *tp = buf_ptr; while (tp < buf_end) if (*tp++ == ')' && (*tp == ';' || *tp == ',')) goto not_proc; strncpy(state->procname, token, sizeof state->procname - 1); if (state->in_decl) state->in_parameter_declaration = 1; return (funcname); not_proc:; } /* * The following hack attempts to guess whether or not the current * token is in fact a declaration keyword -- one that has been * typedefd */ else if (!state->p_l_follow && !state->block_init && !state->in_stmt && ((*buf_ptr == '*' && buf_ptr[1] != '=') || isalpha((unsigned char)*buf_ptr)) && (state->last_token == semicolon || state->last_token == lbrace || state->last_token == rbrace)) { state->keyword = 4; /* a type name */ state->last_u_d = true; return decl; } if (state->last_token == decl) /* if this is a declared variable, * then following sign is unary */ state->last_u_d = true; /* will make "int a -1" work */ return (ident); /* the ident is not in the list */ } /* end of procesing for alpanum character */ /* Scan a non-alphanumeric token */ CHECK_SIZE_TOKEN(3); /* things like "<<=" */ *e_token++ = *buf_ptr; /* if it is only a one-character token, it is * moved here */ *e_token = '\0'; if (++buf_ptr >= buf_end) fill_buffer(); switch (*token) { case '\n': unary_delim = state->last_u_d; state->last_nl = true; /* remember that we just had a newline */ code = (had_eof ? 0 : newline); /* * if data has been exhausted, the newline is a dummy, and we should * return code to stop */ break; case '\'': /* start of quoted character */ case '"': /* start of string */ qchar = *token; do { /* copy the string */ while (1) { /* move one character or [/] */ if (*buf_ptr == '\n') { diag2(1, "Unterminated literal"); goto stop_lit; } CHECK_SIZE_TOKEN(2); *e_token = *buf_ptr++; if (buf_ptr >= buf_end) fill_buffer(); if (*e_token == BACKSLASH) { /* if escape, copy extra char */ if (*buf_ptr == '\n') /* check for escaped newline */ ++line_no; *++e_token = *buf_ptr++; ++e_token; /* we must increment this again because we * copied two chars */ if (buf_ptr >= buf_end) fill_buffer(); } else break; /* we copied one character */ } /* end of while (1) */ } while (*e_token++ != qchar); stop_lit: code = ident; break; case ('('): case ('['): unary_delim = true; code = lparen; break; case (')'): case (']'): code = rparen; break; case '#': unary_delim = state->last_u_d; code = preesc; break; case '?': unary_delim = true; code = question; break; case (':'): code = colon; unary_delim = true; break; case (';'): unary_delim = true; code = semicolon; break; case ('{'): unary_delim = true; /* * if (state->in_or_st) state->block_init = 1; */ /* ? code = state->block_init ? lparen : lbrace; */ code = lbrace; break; case ('}'): unary_delim = true; /* ? code = state->block_init ? rparen : rbrace; */ code = rbrace; break; case 014: /* a form feed */ unary_delim = state->last_u_d; state->last_nl = true; /* remember this so we can set 'state->col_1' * right */ code = form_feed; break; case (','): unary_delim = true; code = comma; break; case '.': unary_delim = false; code = period; break; case '-': case '+': /* check for -, +, --, ++ */ code = (state->last_u_d ? unary_op : binary_op); unary_delim = true; if (*buf_ptr == token[0]) { /* check for doubled character */ *e_token++ = *buf_ptr++; /* buffer overflow will be checked at end of loop */ if (state->last_token == ident || state->last_token == rparen) { code = (state->last_u_d ? unary_op : postop); /* check for following ++ or -- */ unary_delim = false; } } else if (*buf_ptr == '=') /* check for operator += */ *e_token++ = *buf_ptr++; else if (*buf_ptr == '>') { /* check for operator -> */ *e_token++ = *buf_ptr++; unary_delim = false; code = unary_op; state->want_blank = false; } break; /* buffer overflow will be checked at end of * switch */ case '=': if (state->in_or_st) state->block_init = 1; #ifdef undef if (chartype[*buf_ptr & 127] == opchar) { /* we have two char assignment */ e_token[-1] = *buf_ptr++; if ((e_token[-1] == '<' || e_token[-1] == '>') && e_token[-1] == *buf_ptr) *e_token++ = *buf_ptr++; *e_token++ = '='; /* Flip =+ to += */ *e_token = 0; } #else if (*buf_ptr == '=') {/* == */ *e_token++ = '='; /* Flip =+ to += */ buf_ptr++; *e_token = 0; } #endif code = binary_op; unary_delim = true; break; /* can drop thru!!! */ case '>': case '<': case '!': /* ops like <, <<, <=, !=, etc */ if (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=') { *e_token++ = *buf_ptr; if (++buf_ptr >= buf_end) fill_buffer(); } if (*buf_ptr == '=') *e_token++ = *buf_ptr++; code = (state->last_u_d ? unary_op : binary_op); unary_delim = true; break; case '*': unary_delim = true; if (!state->last_u_d) { if (*buf_ptr == '=') *e_token++ = *buf_ptr++; code = binary_op; break; } while (*buf_ptr == '*' || isspace((unsigned char)*buf_ptr)) { if (*buf_ptr == '*') { CHECK_SIZE_TOKEN(1); *e_token++ = *buf_ptr; } if (++buf_ptr >= buf_end) fill_buffer(); } if (ps.in_decl) { char *tp = buf_ptr; while (isalpha((unsigned char)*tp) || isspace((unsigned char)*tp)) { if (++tp >= buf_end) fill_buffer(); } if (*tp == '(') ps.procname[0] = ' '; } code = unary_op; break; default: if (token[0] == '/' && *buf_ptr == '*') { /* it is start of comment */ *e_token++ = '*'; if (++buf_ptr >= buf_end) fill_buffer(); code = comment; unary_delim = state->last_u_d; break; } while (*(e_token - 1) == *buf_ptr || *buf_ptr == '=') { /* * handle ||, &&, etc, and also things as in int *****i */ CHECK_SIZE_TOKEN(1); *e_token++ = *buf_ptr; if (++buf_ptr >= buf_end) fill_buffer(); } code = (state->last_u_d ? unary_op : binary_op); unary_delim = true; } /* end of switch */ if (buf_ptr >= buf_end) /* check for input buffer empty */ fill_buffer(); state->last_u_d = unary_delim; CHECK_SIZE_TOKEN(1); *e_token = '\0'; /* null terminate the token */ return (code); } void alloc_typenames(void) { typenames = (const char **)malloc(sizeof(typenames[0]) * (typename_count = 16)); if (typenames == NULL) err(1, NULL); } void add_typename(const char *key) { int comparison; const char *copy; if (typename_top + 1 >= typename_count) { typenames = realloc((void *)typenames, sizeof(typenames[0]) * (typename_count *= 2)); if (typenames == NULL) err(1, NULL); } if (typename_top == -1) typenames[++typename_top] = copy = strdup(key); else if ((comparison = strcmp(key, typenames[typename_top])) >= 0) { /* take advantage of sorted input */ if (comparison == 0) /* remove duplicates */ return; typenames[++typename_top] = copy = strdup(key); } else { int p; for (p = 0; (comparison = strcmp(key, typenames[p])) > 0; p++) /* find place for the new key */; if (comparison == 0) /* remove duplicates */ return; memmove(&typenames[p + 1], &typenames[p], sizeof(typenames[0]) * (++typename_top - p)); typenames[p] = copy = strdup(key); } if (copy == NULL) err(1, NULL); } Index: head/usr.bin/indent/parse.c =================================================================== --- head/usr.bin/indent/parse.c (revision 334926) +++ head/usr.bin/indent/parse.c (revision 334927) @@ -1,346 +1,346 @@ /*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright (c) 1985 Sun Microsystems, Inc. * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if 0 #ifndef lint static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ #endif #include #include __FBSDID("$FreeBSD$"); #include #include #include "indent_globs.h" #include "indent_codes.h" #include "indent.h" static void reduce(void); void parse(int tk) /* tk: the code for the construct scanned */ { int i; #ifdef debug printf("%2d - %s\n", tk, token); #endif while (ps.p_stack[ps.tos] == ifhead && tk != elselit) { /* true if we have an if without an else */ ps.p_stack[ps.tos] = stmt; /* apply the if(..) stmt ::= stmt * reduction */ reduce(); /* see if this allows any reduction */ } switch (tk) { /* go on and figure out what to do with the * input */ case decl: /* scanned a declaration word */ - ps.search_brace = btype_2; + ps.search_brace = opt.btype_2; /* indicate that following brace should be on same line */ if (ps.p_stack[ps.tos] != decl) { /* only put one declaration * onto stack */ break_comma = true; /* while in declaration, newline should be * forced after comma */ ps.p_stack[++ps.tos] = decl; ps.il[ps.tos] = ps.i_l_follow; - if (ps.ljust_decl) {/* only do if we want left justified + if (opt.ljust_decl) {/* only do if we want left justified * declarations */ ps.ind_level = 0; for (i = ps.tos - 1; i > 0; --i) if (ps.p_stack[i] == decl) ++ps.ind_level; /* indentation is number of * declaration levels deep we are */ ps.i_l_follow = ps.ind_level; } } break; case ifstmt: /* scanned if (...) */ - if (ps.p_stack[ps.tos] == elsehead && ps.else_if) /* "else if ..." */ + if (ps.p_stack[ps.tos] == elsehead && opt.else_if) /* "else if ..." */ /* * Note that the stack pointer here is decremented, effectively * reducing "else if" to "if". This saves a lot of stack space * in case of a long "if-else-if ... else-if" sequence. */ ps.i_l_follow = ps.il[ps.tos--]; /* the rest is the same as for dolit and forstmt */ case dolit: /* 'do' */ case forstmt: /* for (...) */ ps.p_stack[++ps.tos] = tk; ps.il[ps.tos] = ps.ind_level = ps.i_l_follow; ++ps.i_l_follow; /* subsequent statements should be indented 1 */ - ps.search_brace = btype_2; + ps.search_brace = opt.btype_2; break; case lbrace: /* scanned { */ break_comma = false; /* don't break comma in an initial list */ if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl || ps.p_stack[ps.tos] == stmtl) ++ps.i_l_follow; /* it is a random, isolated stmt group or a * declaration */ else { if (s_code == e_code) { /* * only do this if there is nothing on the line */ --ps.ind_level; /* * it is a group as part of a while, for, etc. */ if (ps.p_stack[ps.tos] == swstmt && ps.case_indent >= 1) --ps.ind_level; /* * for a switch, brace should be two levels out from the code */ } } ps.p_stack[++ps.tos] = lbrace; ps.il[ps.tos] = ps.ind_level; ps.p_stack[++ps.tos] = stmt; /* allow null stmt between braces */ ps.il[ps.tos] = ps.i_l_follow; break; case whilestmt: /* scanned while (...) */ if (ps.p_stack[ps.tos] == dohead) { /* it is matched with do stmt */ ps.ind_level = ps.i_l_follow = ps.il[ps.tos]; ps.p_stack[++ps.tos] = whilestmt; ps.il[ps.tos] = ps.ind_level = ps.i_l_follow; } else { /* it is a while loop */ ps.p_stack[++ps.tos] = whilestmt; ps.il[ps.tos] = ps.i_l_follow; ++ps.i_l_follow; - ps.search_brace = btype_2; + ps.search_brace = opt.btype_2; } break; case elselit: /* scanned an else */ if (ps.p_stack[ps.tos] != ifhead) diag2(1, "Unmatched 'else'"); else { ps.ind_level = ps.il[ps.tos]; /* indentation for else should * be same as for if */ ps.i_l_follow = ps.ind_level + 1; /* everything following should * be in 1 level */ ps.p_stack[ps.tos] = elsehead; /* remember if with else */ - ps.search_brace = btype_2 | ps.else_if; + ps.search_brace = opt.btype_2 | opt.else_if; } break; case rbrace: /* scanned a } */ /* stack should have or */ if (ps.tos > 0 && ps.p_stack[ps.tos - 1] == lbrace) { ps.ind_level = ps.i_l_follow = ps.il[--ps.tos]; ps.p_stack[ps.tos] = stmt; } else diag2(1, "Statement nesting error"); break; case swstmt: /* had switch (...) */ ps.p_stack[++ps.tos] = swstmt; ps.cstk[ps.tos] = case_ind; /* save current case indent level */ ps.il[ps.tos] = ps.i_l_follow; case_ind = ps.i_l_follow + ps.case_indent; /* cases should be one * level down from * switch */ ps.i_l_follow += ps.case_indent + 1; /* statements should be two * levels in */ - ps.search_brace = btype_2; + ps.search_brace = opt.btype_2; break; case semicolon: /* this indicates a simple stmt */ break_comma = false; /* turn off flag to break after commas in a * declaration */ ps.p_stack[++ps.tos] = stmt; ps.il[ps.tos] = ps.ind_level; break; default: /* this is an error */ diag2(1, "Unknown code to parser"); return; } /* end of switch */ if (ps.tos >= (int)nitems(ps.p_stack) - 1) errx(1, "Parser stack overflow"); reduce(); /* see if any reduction can be done */ #ifdef debug for (i = 1; i <= ps.tos; ++i) printf("(%d %d)", ps.p_stack[i], ps.il[i]); printf("\n"); #endif return; } /* * NAME: reduce * * FUNCTION: Implements the reduce part of the parsing algorithm * * ALGORITHM: The following reductions are done. Reductions are repeated * until no more are possible. * * Old TOS New TOS * * * do "dostmt" * if "ifstmt" * switch * decl * "ifelse" * for * while * "dostmt" while * * On each reduction, ps.i_l_follow (the indentation for the following line) * is set to the indentation level associated with the old TOS. * * PARAMETERS: None * * RETURNS: Nothing * * GLOBALS: ps.cstk ps.i_l_follow = ps.il ps.p_stack = ps.tos = * * CALLS: None * * CALLED BY: parse * * HISTORY: initial coding November 1976 D A Willcox of CAC * */ /*----------------------------------------------*\ | REDUCTION PHASE | \*----------------------------------------------*/ static void reduce(void) { int i; for (;;) { /* keep looping until there is nothing left to * reduce */ switch (ps.p_stack[ps.tos]) { case stmt: switch (ps.p_stack[ps.tos - 1]) { case stmt: case stmtl: /* stmtl stmt or stmt stmt */ ps.p_stack[--ps.tos] = stmtl; break; case dolit: /* */ ps.p_stack[--ps.tos] = dohead; ps.i_l_follow = ps.il[ps.tos]; break; case ifstmt: /* */ ps.p_stack[--ps.tos] = ifhead; for (i = ps.tos - 1; ( ps.p_stack[i] != stmt && ps.p_stack[i] != stmtl && ps.p_stack[i] != lbrace ); --i); ps.i_l_follow = ps.il[i]; /* * for the time being, we will assume that there is no else on * this if, and set the indentation level accordingly. If an * else is scanned, it will be fixed up later */ break; case swstmt: /* */ case_ind = ps.cstk[ps.tos - 1]; /* FALLTHROUGH */ case decl: /* finish of a declaration */ case elsehead: /* < else> */ case forstmt: /* */ case whilestmt: /* */ ps.p_stack[--ps.tos] = stmt; ps.i_l_follow = ps.il[ps.tos]; break; default: /* */ return; } /* end of section for on top of stack */ break; case whilestmt: /* while (...) on top */ if (ps.p_stack[ps.tos - 1] == dohead) { /* it is termination of a do while */ ps.tos -= 2; break; } else return; default: /* anything else on top */ return; } } } Index: head/usr.bin/indent/pr_comment.c =================================================================== --- head/usr.bin/indent/pr_comment.c (revision 334926) +++ head/usr.bin/indent/pr_comment.c (revision 334927) @@ -1,354 +1,355 @@ /*- * SPDX-License-Identifier: BSD-4-Clause * * Copyright (c) 1985 Sun Microsystems, Inc. * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if 0 #ifndef lint static char sccsid[] = "@(#)pr_comment.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ #endif #include __FBSDID("$FreeBSD$"); #include #include #include #include #include "indent_globs.h" #include "indent_codes.h" #include "indent.h" /* * NAME: * pr_comment * * FUNCTION: * This routine takes care of scanning and printing comments. * * ALGORITHM: * 1) Decide where the comment should be aligned, and if lines should * be broken. * 2) If lines should not be broken and filled, just copy up to end of * comment. * 3) If lines should be filled, then scan thru input_buffer copying * characters to com_buf. Remember where the last blank, tab, or * newline was. When line is filled, print up to last blank and * continue copying. * * HISTORY: * November 1976 D A Willcox of CAC Initial coding * 12/6/76 D A Willcox of CAC Modification to handle * UNIX-style comments * */ /* * this routine processes comments. It makes an attempt to keep comments from * going over the max line length. If a line is too long, it moves everything * from the last blank to the next comment line. Blanks and tabs from the * beginning of the input line are removed */ void pr_comment(void) { int now_col; /* column we are in now */ int adj_max_col; /* Adjusted max_col for when we decide to * spill comments over the right margin */ char *last_bl; /* points to the last blank in the output * buffer */ char *t_ptr; /* used for moving string */ - int break_delim = comment_delimiter_on_blankline; + int break_delim = opt.comment_delimiter_on_blankline; int l_just_saw_decl = ps.just_saw_decl; - adj_max_col = max_col; + + adj_max_col = opt.max_col; ps.just_saw_decl = 0; last_bl = NULL; /* no blanks found so far */ ps.box_com = false; /* at first, assume that we are not in * a boxed comment or some other * comment that should not be touched */ ++ps.out_coms; /* keep track of number of comments */ /* Figure where to align and how to treat the comment */ - if (ps.col_1 && !format_col1_comments) { /* if comment starts in column + if (ps.col_1 && !opt.format_col1_comments) { /* if comment starts in column * 1 it should not be touched */ ps.box_com = true; break_delim = false; ps.com_col = 1; } else { if (*buf_ptr == '-' || *buf_ptr == '*' || - (*buf_ptr == '\n' && !format_block_comments)) { + (*buf_ptr == '\n' && !opt.format_block_comments)) { ps.box_com = true; /* A comment with a '-' or '*' immediately * after the /+* is assumed to be a boxed * comment. A comment with a newline * immediately after the /+* is assumed to * be a block comment and is treated as a * box comment unless format_block_comments * is nonzero (the default). */ break_delim = false; } if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) { /* klg: check only if this line is blank */ /* * If this (*and previous lines are*) blank, dont put comment way * out at left */ - ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1; - adj_max_col = block_comment_max_col; + ps.com_col = (ps.ind_level - opt.unindent_displace) * opt.ind_size + 1; + adj_max_col = opt.block_comment_max_col; if (ps.com_col <= 1) - ps.com_col = 1 + !format_col1_comments; + ps.com_col = 1 + !opt.format_col1_comments; } else { int target_col; break_delim = false; if (s_code != e_code) target_col = count_spaces(compute_code_target(), s_code); else { target_col = 1; if (s_lab != e_lab) target_col = count_spaces(compute_label_target(), s_lab); } - ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? ps.decl_com_ind : ps.com_ind; + ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? opt.decl_com_ind : opt.com_ind; if (ps.com_col <= target_col) - ps.com_col = tabsize * (1 + (target_col - 1) / tabsize) + 1; + ps.com_col = opt.tabsize * (1 + (target_col - 1) / opt.tabsize) + 1; if (ps.com_col + 24 > adj_max_col) adj_max_col = ps.com_col + 24; } } if (ps.box_com) { /* * Find out how much indentation there was originally, because that * much will have to be ignored by pad_output() in dump_line(). This * is a box comment, so nothing changes -- not even indentation. * * The comment we're about to read usually comes from in_buffer, * unless it has been copied into save_com. */ char *start; start = buf_ptr >= save_com && buf_ptr < save_com + sc_size ? sc_buf : in_buffer; ps.n_comment_delta = 1 - count_spaces_until(1, start, buf_ptr - 2); } else { ps.n_comment_delta = 0; while (*buf_ptr == ' ' || *buf_ptr == '\t') buf_ptr++; } ps.comment_delta = 0; *e_com++ = '/'; /* put '/' followed by '*' into buffer */ *e_com++ = '*'; if (*buf_ptr != ' ' && !ps.box_com) *e_com++ = ' '; /* * Don't put a break delimiter if this is a one-liner that won't wrap. */ if (break_delim) for (t_ptr = buf_ptr; *t_ptr != '\0' && *t_ptr != '\n'; t_ptr++) { if (t_ptr >= buf_end) fill_buffer(); if (t_ptr[0] == '*' && t_ptr[1] == '/') { if (adj_max_col >= count_spaces_until(ps.com_col, buf_ptr, t_ptr + 2)) break_delim = false; break; } } if (break_delim) { char *t = e_com; e_com = s_com + 2; *e_com = 0; - if (blanklines_before_blockcomments && ps.last_token != lbrace) + if (opt.blanklines_before_blockcomments && ps.last_token != lbrace) prefix_blankline_requested = 1; dump_line(); e_com = s_com = t; - if (!ps.box_com && star_comment_cont) + if (!ps.box_com && opt.star_comment_cont) *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; } /* Start to copy the comment */ while (1) { /* this loop will go until the comment is * copied */ switch (*buf_ptr) { /* this checks for various spcl cases */ case 014: /* check for a form feed */ CHECK_SIZE_COM(3); if (!ps.box_com) { /* in a text comment, break the line here */ ps.use_ff = true; /* fix so dump_line uses a form feed */ dump_line(); last_bl = NULL; - if (!ps.box_com && star_comment_cont) + if (!ps.box_com && opt.star_comment_cont) *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; while (*++buf_ptr == ' ' || *buf_ptr == '\t') ; } else { if (++buf_ptr >= buf_end) fill_buffer(); *e_com++ = 014; } break; case '\n': if (had_eof) { /* check for unexpected eof */ printf("Unterminated comment\n"); dump_line(); return; } last_bl = NULL; CHECK_SIZE_COM(4); if (ps.box_com || ps.last_nl) { /* if this is a boxed comment, * we dont ignore the newline */ if (s_com == e_com) *e_com++ = ' '; if (!ps.box_com && e_com - s_com > 3) { dump_line(); - if (star_comment_cont) + if (opt.star_comment_cont) *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; } dump_line(); - if (!ps.box_com && star_comment_cont) + if (!ps.box_com && opt.star_comment_cont) *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; } else { ps.last_nl = 1; if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t') last_bl = e_com - 1; /* * if there was a space at the end of the last line, remember * where it was */ else { /* otherwise, insert one */ last_bl = e_com; *e_com++ = ' '; } } ++line_no; /* keep track of input line number */ if (!ps.box_com) { int nstar = 1; do { /* flush any blanks and/or tabs at start of * next line */ if (++buf_ptr >= buf_end) fill_buffer(); if (*buf_ptr == '*' && --nstar >= 0) { if (++buf_ptr >= buf_end) fill_buffer(); if (*buf_ptr == '/') goto end_of_comment; } } while (*buf_ptr == ' ' || *buf_ptr == '\t'); } else if (++buf_ptr >= buf_end) fill_buffer(); break; /* end of case for newline */ case '*': /* must check for possibility of being at end * of comment */ if (++buf_ptr >= buf_end) /* get to next char after * */ fill_buffer(); CHECK_SIZE_COM(4); if (*buf_ptr == '/') { /* it is the end!!! */ end_of_comment: if (++buf_ptr >= buf_end) fill_buffer(); if (break_delim) { if (e_com > s_com + 3) { dump_line(); } else s_com = e_com; *e_com++ = ' '; } if (e_com[-1] != ' ' && e_com[-1] != '\t' && !ps.box_com) *e_com++ = ' '; /* ensure blank before end */ *e_com++ = '*', *e_com++ = '/', *e_com = '\0'; ps.just_saw_decl = l_just_saw_decl; return; } else /* handle isolated '*' */ *e_com++ = '*'; break; default: /* we have a random char */ now_col = count_spaces_until(ps.com_col, s_com, e_com); do { CHECK_SIZE_COM(1); *e_com = *buf_ptr++; if (buf_ptr >= buf_end) fill_buffer(); if (*e_com == ' ' || *e_com == '\t') last_bl = e_com; /* remember we saw a blank */ ++e_com; now_col++; } while (!memchr("*\n\r\b\t", *buf_ptr, 6) && (now_col <= adj_max_col || !last_bl)); ps.last_nl = false; if (now_col > adj_max_col && !ps.box_com && e_com[-1] > ' ') { /* * the comment is too long, it must be broken up */ if (last_bl == NULL) { dump_line(); - if (!ps.box_com && star_comment_cont) + if (!ps.box_com && opt.star_comment_cont) *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; break; } *e_com = '\0'; e_com = last_bl; dump_line(); - if (!ps.box_com && star_comment_cont) + if (!ps.box_com && opt.star_comment_cont) *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; for (t_ptr = last_bl + 1; *t_ptr == ' ' || *t_ptr == '\t'; t_ptr++) ; last_bl = NULL; /* * t_ptr will be somewhere between e_com (dump_line() reset) * and l_com. So it's safe to copy byte by byte from t_ptr * to e_com without any CHECK_SIZE_COM(). */ while (*t_ptr != '\0') { if (*t_ptr == ' ' || *t_ptr == '\t') last_bl = e_com; *e_com++ = *t_ptr++; } } break; } } }