From 97c7d358ea5970ca59196ed90e975115245f9e76 Mon Sep 17 00:00:00 2001 From: Vivek Prakash Date: Sat, 2 Jul 2011 23:26:53 +0000 Subject: [PATCH] Replace indent with NetBSD version - minix-port.patch is empty as it compiles unchanged --- commands/Makefile | 2 +- commands/indent/Makefile | 7 - commands/indent/args.c | 287 ------- commands/indent/codes.h | 54 -- commands/indent/comment.c | 457 ---------- commands/indent/globs.h | 308 ------- commands/indent/indent.c | 1374 ------------------------------- commands/indent/indent.pro | 1 - commands/indent/io.c | 636 -------------- commands/indent/lexi.c | 571 ------------- commands/indent/parse.c | 319 ------- commands/indent/proto.h | 26 - tools/nbsd_ports | 1 + usr.bin/Makefile | 2 +- usr.bin/indent/Makefile | 7 + usr.bin/indent/README | 97 +++ usr.bin/indent/args.c | 461 +++++++++++ usr.bin/indent/indent.1 | 562 +++++++++++++ usr.bin/indent/indent.c | 1281 ++++++++++++++++++++++++++++ usr.bin/indent/indent_codes.h | 101 +++ usr.bin/indent/indent_globs.h | 363 ++++++++ usr.bin/indent/io.c | 685 +++++++++++++++ usr.bin/indent/lexi.c | 630 ++++++++++++++ usr.bin/indent/minix-port.patch | 0 usr.bin/indent/parse.c | 360 ++++++++ usr.bin/indent/pr_comment.c | 461 +++++++++++ 26 files changed, 5011 insertions(+), 4042 deletions(-) delete mode 100644 commands/indent/Makefile delete mode 100644 commands/indent/args.c delete mode 100644 commands/indent/codes.h delete mode 100644 commands/indent/comment.c delete mode 100644 commands/indent/globs.h delete mode 100644 commands/indent/indent.c delete mode 100644 commands/indent/indent.pro delete mode 100644 commands/indent/io.c delete mode 100644 commands/indent/lexi.c delete mode 100644 commands/indent/parse.c delete mode 100644 commands/indent/proto.h create mode 100644 usr.bin/indent/Makefile create mode 100644 usr.bin/indent/README create mode 100644 usr.bin/indent/args.c create mode 100644 usr.bin/indent/indent.1 create mode 100644 usr.bin/indent/indent.c create mode 100644 usr.bin/indent/indent_codes.h create mode 100644 usr.bin/indent/indent_globs.h create mode 100644 usr.bin/indent/io.c create mode 100644 usr.bin/indent/lexi.c create mode 100644 usr.bin/indent/minix-port.patch create mode 100644 usr.bin/indent/parse.c create mode 100644 usr.bin/indent/pr_comment.c diff --git a/commands/Makefile b/commands/Makefile index 02705a1e5..bfb12d4ef 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -13,7 +13,7 @@ SUBDIR= aal add_route adduser advent arp ash at autil awk \ ed eject elle elvis env expand factor file \ find finger fingerd fix fold format fortune fsck.mfs \ ftp101 ftpd200 gcov-pull getty grep gomoku head hexdump host \ - hostaddr id ifconfig ifdef indent install \ + hostaddr id ifconfig ifdef install \ intr ipcrm ipcs irdpd isoread join kill last leave \ less lex life loadkeys loadramdisk logger login look lp \ lpd ls lspci M mail make MAKEDEV man \ diff --git a/commands/indent/Makefile b/commands/indent/Makefile deleted file mode 100644 index 03f7e0ca6..000000000 --- a/commands/indent/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# Makefile for indent - -PROG= indent -SRCS= args.c comment.c lexi.c indent.c parse.c io.c -MAN= - -.include diff --git a/commands/indent/args.c b/commands/indent/args.c deleted file mode 100644 index 729452d5b..000000000 --- a/commands/indent/args.c +++ /dev/null @@ -1,287 +0,0 @@ -/** - * Copyright (c) 1985 Sun Microsystems, Inc. - * Copyright (c) 1980 The Regents of the University of California. - * Copyright (c) 1976 Board of Trustees of the University of Illinois. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley, the University of Illinois, - * Urbana, and Sun Microsystems, Inc. The name of either University - * or Sun Microsystems may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -/* - * Argument scanning and profile reading code. Default parameters are set - * here as well. - */ - -#define PUBLIC extern -#include -#include -#include -#include -#include "globs.h" -#include "proto.h" - -/* profile types */ -#define PRO_SPECIAL 1 /* special case */ -#define PRO_BOOL 2 /* boolean */ -#define PRO_INT 3 /* integer */ -#define PRO_FONT 4 /* troff font */ - -/* 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) */ - -/* - * 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 -{ - char *p_name; /* name, eg -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, - "bacc", PRO_BOOL, false, ON, &bl_around, - "badp", PRO_BOOL, false, ON, &bl_at_proctop, - "bad", PRO_BOOL, false, ON, &bl_aft_decl, - "bap", PRO_BOOL, false, ON, &bl_a_procs, - "bbb", PRO_BOOL, false, ON, &bl_bef_bk, - "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, &del_on_bl, - "cd", PRO_INT, 0, 0, &ps.decl_com_ind, - "ce", PRO_BOOL, true, ON, &cuddle_else, - "ci", PRO_INT, 0, 0, &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, &ex_expr_indent, - "ei", PRO_BOOL, true, ON, &ps.else_if, - "fbc", PRO_FONT, 0, 0, (int *) &blkcomf, - "fbx", PRO_FONT, 0, 0, (int *) &boxcomf, - "fb", PRO_FONT, 0, 0, (int *) &bodyf, - "fc1", PRO_BOOL, true, ON, &format_col1_comments, - "fc", PRO_FONT, 0, 0, (int *) &scomf, - "fk", PRO_FONT, 0, 0, (int *) &keywordf, - "fs", PRO_FONT, 0, 0, (int *) &stringf, - "ip", PRO_BOOL, true, ON, &ps.indent_parameters, - "i", PRO_INT, 8, 0, &ps.ind_size, - "lc", PRO_INT, 0, 0, &bk_max_col, - "lp", PRO_BOOL, true, ON, &lineup_to_parens, - "l", PRO_INT, 78, 0, &max_col, - "nbacc", PRO_BOOL, false, OFF, &bl_around, - "nbadp", PRO_BOOL, false, OFF, &bl_at_proctop, - "nbad", PRO_BOOL, false, OFF, &bl_aft_decl, - "nbap", PRO_BOOL, false, OFF, &bl_a_procs, - "nbbb", PRO_BOOL, false, OFF, &bl_bef_bk, - "nbc", PRO_BOOL, true, ON, &ps.leave_comma, - "nbs", PRO_BOOL, false, OFF, &Bill_Shannon, - "ncdb", PRO_BOOL, true, OFF, &del_on_bl, - "nce", PRO_BOOL, true, OFF, &cuddle_else, - "ndj", PRO_BOOL, false, OFF, &ps.ljust_decl, - "neei", PRO_BOOL, false, OFF, &ex_expr_indent, - "nei", PRO_BOOL, true, OFF, &ps.else_if, - "nfc1", PRO_BOOL, true, OFF, &format_col1_comments, - "nip", PRO_BOOL, true, OFF, &ps.indent_parameters, - "nlp", PRO_BOOL, true, OFF, &lineup_to_parens, - "npcs", PRO_BOOL, false, OFF, &proc_calls_space, - "npro", PRO_SPECIAL, 0, IGN, 0, - "npsl", PRO_BOOL, true, OFF, &proc_str_line, - "nps", PRO_BOOL, false, OFF, &ptr_binop, - "nsc", PRO_BOOL, true, OFF, &star_comment_cont, - "nsob", PRO_BOOL, false, OFF, &swallow_opt_bl, - "nv", PRO_BOOL, false, OFF, &verbose, - "pcs", PRO_BOOL, false, ON, &proc_calls_space, - "psl", PRO_BOOL, true, ON, &proc_str_line, - "ps", PRO_BOOL, false, ON, &ptr_binop, - "sc", PRO_BOOL, true, ON, &star_comment_cont, - "sob", PRO_BOOL, false, ON, &swallow_opt_bl, - "st", PRO_SPECIAL, 0, STDIN, 0, - "troff", PRO_BOOL, false, ON, &troff, - "v", PRO_BOOL, false, ON, &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() -{ - register FILE *f; - char fname[BUFSIZ]; - static char prof[] = ".indent.pro"; - - sprintf(fname, "%s/%s", getenv("HOME"), prof); - if ((f = fopen(fname, "r")) != NULL) - { - scan_profile(f); - (void) fclose(f); - } - if ((f = fopen(prof, "r")) != NULL) - { - scan_profile(f); - (void) fclose(f); - } -} - -void scan_profile(f) - register FILE *f; -{ - register int i; - register char *p; - char buf[BUFSIZ]; - - while (1) - { - for (p = buf; (i = getc(f)) != EOF && (*p = (char)i) > ' '; ++p); - if (p != buf) - { - *p++ = 0; - if (verbose) - printf("profile: %s\n", buf); - set_option(buf); - } else if (i == EOF) - return; - } -} - -char *param_start; - -int eqin(s1, s2) - register char *s1; - register char *s2; -{ - while (*s1) - { - if (*s1++ != *s2++) - return (false); - } - param_start = s2; - return (true); -} - -/* - * Set the defaults. - */ -void set_defaults() -{ - register struct pro *p; - - /* Because ps.case_indent is a float, we can't initialize it from - the table: */ - ps.case_indent = 0; /* -cli0.0 */ - for (p = pro; p->p_name; p++) - if (p->p_type != PRO_SPECIAL && p->p_type != PRO_FONT) - *p->p_obj = p->p_default; -} - -void set_option(arg) - register char *arg; -{ - register struct pro *p; - - arg++; /* ignore leading "-" */ - for (p = pro; p->p_name; p++) - if (*p->p_name == *arg && eqin(p->p_name, arg)) - goto found; - fprintf(stderr, "indent: unknown parameter \"%s\"\n", arg - 1); - exit(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 = atoi(param_start); - break; - - case STDIN: - if (input == 0) - input = stdin; - if (output == 0) - output = stdout; - break; - - case KEY: - if (*param_start == 0) - goto need_param; - { - register char *str = (char *) malloc(strlen(param_start) + 1); - strcpy(str, param_start); - addkey(str, 4); - } - break; - - default: - fprintf(stderr, "\ -indent: set_option: internal error: p_special %d\n", p->p_special); - exit(1); - } - break; - - case PRO_BOOL: - if (p->p_special == OFF) - *p->p_obj = false; - else - *p->p_obj = true; - break; - - case PRO_INT: - if (*param_start == 0) - { - need_param: - fprintf(stderr, "indent: ``%s'' requires a parameter\n", - arg - 1); - exit(1); - } - *p->p_obj = atoi(param_start); - break; - - case PRO_FONT: - parsefont((struct fstate *) p->p_obj, param_start); - break; - - default: - fprintf(stderr, "indent: set_option: internal error: p_type %d\n", - p->p_type); - exit(1); - } -} diff --git a/commands/indent/codes.h b/commands/indent/codes.h deleted file mode 100644 index 1afea04cd..000000000 --- a/commands/indent/codes.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Copyright (c) 1985 Sun Microsystems, Inc. - * Copyright (c) 1980 The Regents of the University of California. - * Copyright (c) 1976 Board of Trustees of the University of Illinois. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley, the University of Illinois, - * Urbana, and Sun Microsystems, Inc. The name of either University - * or Sun Microsystems may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * @(#)indent_codes.h 5.6 (Berkeley) 9/15/88 - */ - -#define newline 1 -#define lparen 2 -#define rparen 3 -#define unary_op 4 -#define binary_op 5 -#define postop 6 -#define question 7 -#define casestmt 8 -#define colon 9 -#define semicolon 10 -#define lbrace 11 -#define rbrace 12 -#define ident 13 -#define comma 14 -#define comment 15 -#define swstmt 16 -#define preesc 17 -#define form_feed 18 -#define decl 19 -#define sp_paren 20 -#define sp_nparen 21 -#define ifstmt 22 -#define whilestmt 23 -#define forstmt 24 -#define stmt 25 -#define stmtl 26 -#define elselit 27 -#define dolit 28 -#define dohead 29 -#define ifhead 30 -#define elsehead 31 -#define period 32 diff --git a/commands/indent/comment.c b/commands/indent/comment.c deleted file mode 100644 index a4625a46f..000000000 --- a/commands/indent/comment.c +++ /dev/null @@ -1,457 +0,0 @@ -/** - * Copyright (c) 1985 Sun Microsystems, Inc. - * Copyright (c) 1980 The Regents of the University of California. - * Copyright (c) 1976 Board of Trustees of the University of Illinois. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley, the University of Illinois, - * Urbana, and Sun Microsystems, Inc. The name of either University - * or Sun Microsystems may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -/* - * 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 - * 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 - */ - - -#define PUBLIC extern -#include -#include "globs.h" -#include "proto.h" - - -void pr_comment() -{ - 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 unix_comment; /* tri-state variable used to - * decide if it is a unix-style - * comment. 0 means only blanks - * since / *, 1 means regular - * style comment, 2 means unix - * style comment - */ - - int break_delim = del_on_bl; - int l_just_saw_decl = ps.just_saw_decl; - /* int ps.last_nl = 0; */ /* true iff the last - sig thing we have seen is a nl */ - - int one_liner = 1; /* true iff this comment is a - one-liner */ - adj_max_col = max_col; - ps.just_saw_decl = 0; - last_bl = 0; /* 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 */ - unix_comment = 1; /* set flag to let us figure - out if there is a unix-style - comment ** DISABLED: use 0 - to reenable this hack! */ - - /* Figure where to align and how to treat the comment */ - - if (ps.col_1 && !format_col1_comments) - { /* if comment starts in column - 1 it should not be touched */ - ps.box_com = true; - ps.com_col = 1; - } else - { - if (*buf_ptr == '-' || *buf_ptr == '*') - { - ps.box_com = true; /* a comment with a '-' or '*' - immediately after the / * is - assumed to be a boxed - comment */ - break_delim = 0; - } - 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 = bk_max_col; - if (ps.com_col <= 1) - ps.com_col = 1 + !format_col1_comments; - } else - { - register target_col; - break_delim = 0; - if (s_code != e_code) - target_col = count_spaces(code_target(), s_code); - else - { - target_col = 1; - if (s_lab != e_lab) - target_col = count_spaces(label_target(), s_lab); - } - ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? ps.decl_com_ind : ps.com_ind; - if (ps.com_col < target_col) - ps.com_col = ((target_col + 7) & ~7) + 1; - if (ps.com_col + 24 > adj_max_col) - adj_max_col = ps.com_col + 24; - } - } - if (ps.box_com) - { - buf_ptr[-2] = 0; - ps.n_comment_delta = 1 - count_spaces(1, in_buffer); - buf_ptr[-2] = '/'; - } else - { - ps.n_comment_delta = 0; - while (*buf_ptr == ' ' || *buf_ptr == '\t') - buf_ptr++; - } - ps.comment_delta = 0; - *e_com++ = '/'; /* put '/ *' into buffer */ - *e_com++ = '*'; - if (*buf_ptr != ' ' && !ps.box_com) - *e_com++ = ' '; - - *e_com = '\0'; - if (troff) - { - now_col = 1; - adj_max_col = 80; - } else - now_col = count_spaces(ps.com_col, s_com); /* figure what column we - would be in if we - printed the comment - now */ - - /* Start to copy the comment */ - - while (1) - { /* this loop will go until the - comment is copied */ - if (*buf_ptr > 040 && *buf_ptr != '*') - ps.last_nl = 0; - if (e_com >= l_com) - { - register nsize = l_com - s_com + 400; - combuf = (char *) realloc(combuf, nsize); - e_com = combuf + (e_com - s_com) + 1; - l_com = combuf + nsize - 5; - s_com = combuf + 1; - } - switch (*buf_ptr) - { /* this checks for various spcl - cases */ - case 014: /* check for a form feed */ - 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 = 0; - *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"); - *e_com = '\0'; - dump_line(); - return; - } - one_liner = 0; - 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++ = ' '; - *e_com++ = ' '; - } - *e_com = '\0'; - if (!ps.box_com && e_com - s_com > 3) - { - if (break_delim == 1 && s_com[0] == '/' - && s_com[1] == '*' && s_com[2] == ' ') - { - char *t = e_com; - break_delim = 2; - e_com = s_com + 2; - *e_com = 0; - if (bl_bef_bk) - prefix_blankline_requested = 1; - dump_line(); - e_com = t; - s_com[0] = s_com[1] = s_com[2] = ' '; - } - dump_line(); - if (e_com >= l_com) - { - register nsize = l_com - s_com + 400; - combuf = (char *) realloc(combuf, nsize); - e_com = combuf + (e_com - s_com) + 1; - l_com = combuf + nsize - 5; - s_com = combuf + 1; - } - *e_com++ = ' '; - *e_com++ = ' '; - } - dump_line(); - now_col = ps.com_col; - } else - { - ps.last_nl = 1; - if (unix_comment != 1) - { /* we not are in unix_style - comment */ - if (unix_comment == 0 && s_code == e_code) - { - /* if it is a UNIX-style comment, ignore the - requirement that previous line be blank for - unindention */ - ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1; - if (ps.com_col <= 1) - ps.com_col = 2; - } - unix_comment = 2; /* permanently remember that we - are in this type of comment */ - dump_line(); - ++line_no; - now_col = ps.com_col; - *e_com++ = ' '; - /* fix so that the star at the start of the line will - line up */ - do /* flush leading white space */ - if (++buf_ptr >= buf_end) - fill_buffer(); - while (*buf_ptr == ' ' || *buf_ptr == '\t'); - break; - } - 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++ = ' '; - if (e_com >= l_com) - { - register nsize = l_com - s_com + 400; - combuf = (char *) realloc(combuf, nsize); - e_com = combuf + (e_com - s_com) + 1; - l_com = combuf + nsize - 5; - s_com = combuf + 1; - } - ++now_col; - } - } - ++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(); - - if (unix_comment == 0) /* set flag to show we are not - in unix-style comment */ - unix_comment = 1; - - if (*buf_ptr == '/') - { /* it is the end!!! */ - end_of_comment: - if (++buf_ptr >= buf_end) - fill_buffer(); - - if (*(e_com - 1) != ' ' && !ps.box_com) - { /* insure blank before end */ - *e_com++ = ' '; - ++now_col; - } - if (break_delim == 1 && !one_liner && s_com[0] == '/' - && s_com[1] == '*' && s_com[2] == ' ') - { - char *t = e_com; - break_delim = 2; - e_com = s_com + 2; - *e_com = 0; - if (bl_bef_bk) - prefix_blankline_requested = 1; - dump_line(); - e_com = t; - s_com[0] = s_com[1] = s_com[2] = ' '; - } - if (break_delim == 2 && e_com > s_com + 3 - /* now_col > adj_max_col - 2 && !ps.box_com */ ) - { - *e_com = '\0'; - dump_line(); - now_col = ps.com_col; - } - if (e_com >= l_com) - { - register nsize = l_com - s_com + 400; - combuf = (char *) realloc(combuf, nsize); - e_com = combuf + (e_com - s_com) + 1; - l_com = combuf + nsize - 5; - s_com = combuf + 1; - } - *e_com++ = '*'; - *e_com++ = '/'; - *e_com = '\0'; - ps.just_saw_decl = l_just_saw_decl; - return; - } else - { /* handle isolated '*' */ - *e_com++ = '*'; - ++now_col; - } - break; - default: /* we have a random char */ - if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t') - unix_comment = 1; /* we are not in unix-style - comment */ - - *e_com = *buf_ptr++; - if (buf_ptr >= buf_end) - fill_buffer(); - - if (*e_com == '\t') /* keep track of column */ - now_col = ((now_col - 1) & tabmask) + tabsize + 1; - else if (*e_com == '\b') /* this is a backspace */ - --now_col; - else - ++now_col; - - if (*e_com == ' ' || *e_com == '\t') - last_bl = e_com; - /* remember we saw a blank */ - - ++e_com; - if (now_col > adj_max_col && !ps.box_com && unix_comment == 1 && e_com[-1] > ' ') - { - /* the comment is too long, it must be broken up */ - if (break_delim == 1 && s_com[0] == '/' - && s_com[1] == '*' && s_com[2] == ' ') - { - char *t = e_com; - break_delim = 2; - e_com = s_com + 2; - *e_com = 0; - if (bl_bef_bk) - prefix_blankline_requested = 1; - dump_line(); - e_com = t; - s_com[0] = s_com[1] = s_com[2] = ' '; - } - if (last_bl == 0) - { /* we have seen no blanks */ - last_bl = e_com; /* fake it */ - *e_com++ = ' '; - } - *e_com = '\0'; /* print what we have */ - *last_bl = '\0'; - while (last_bl > s_com && last_bl[-1] < 040) - *--last_bl = 0; - e_com = last_bl; - dump_line(); - - *e_com++ = ' '; /* add blanks for continuation */ - *e_com++ = ' '; - *e_com++ = ' '; - - t_ptr = last_bl + 1; - last_bl = 0; - if (t_ptr >= e_com) - { - while (*t_ptr == ' ' || *t_ptr == '\t') - t_ptr++; - while (*t_ptr != '\0') - { /* move unprinted part of - comment down in buffer */ - if (*t_ptr == ' ' || *t_ptr == '\t') - last_bl = e_com; - *e_com++ = *t_ptr++; - } - } - *e_com = '\0'; - now_col = count_spaces(ps.com_col, s_com); /* recompute current - position */ - } - break; - } - } -} diff --git a/commands/indent/globs.h b/commands/indent/globs.h deleted file mode 100644 index cfd587829..000000000 --- a/commands/indent/globs.h +++ /dev/null @@ -1,308 +0,0 @@ -/** - * Copyright (c) 1985 Sun Microsystems, Inc. - * Copyright (c) 1980 The Regents of the University of California. - * Copyright (c) 1976 Board of Trustees of the University of Illinois. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley, the University of Illinois, - * Urbana, and Sun Microsystems, Inc. The name of either University - * or Sun Microsystems may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * @(#)indent_globs.h 5.7 (Berkeley) 9/15/88 - */ - -#include - -#define BACKSLASH '\\' -#define bufsize 200 /* size of internal buffers */ -#define inp_bufs 600 /* size of input buffer */ -#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 tabsize 8 /* the size of a tab */ -#define tabmask 0177770 /* mask used when figuring - length of lines with tabs */ - - -#define false 0 -#define true !false - - -PUBLIC FILE *input; /* the fid for the input file */ -PUBLIC FILE *output; /* the output file */ - -PUBLIC char *labbuf; /* buffer for label */ -PUBLIC char *s_lab; /* start ... */ -PUBLIC char *e_lab; /* .. and end of stored label */ -PUBLIC char *l_lab; /* limit of label buffer */ - -PUBLIC char *codebuf; /* buffer for code section */ -PUBLIC char *s_code; /* start ... */ -PUBLIC char *e_code; /* .. and end of stored code */ -PUBLIC char *l_code; /* limit of code section */ - -PUBLIC char *combuf; /* buffer for comments */ -PUBLIC char *s_com; /* start ... */ -PUBLIC char *e_com; /* ... and end of stored - comments */ -PUBLIC char *l_com; /* limit of comment buffer */ - -PUBLIC char in_buffer[inp_bufs]; /* input buffer */ -PUBLIC char *buf_ptr; /* ptr to next character to be - taken from in_buffer */ -PUBLIC char *buf_end; /* ptr to first after last char - in in_buffer */ - -PUBLIC char save_com[sc_size]; /* input text is saved here - when looking for the brace - after an if, while, etc */ -PUBLIC char *sc_end; /* pointer into save_com buffer */ - -PUBLIC char *bp_save; /* saved value of buf_ptr when - taking input from save_com */ -PUBLIC char *be_save; /* similarly saved value of - buf_end */ - -PUBLIC char token[bufsize]; /* the last token scanned */ - - -PUBLIC int ptr_binop; /* pointer as binop */ -PUBLIC int bl_aft_decl; /* blanklines after - declarations */ -PUBLIC int bl_bef_bk; /* blanklines before - blockcomments */ -PUBLIC int bl_a_procs; /* blanklines after procs */ -PUBLIC int bl_around; /* blanklines around - conditional compilation */ -PUBLIC int swallow_opt_bl; /* swallow optional blanklines */ -PUBLIC int n_real_blanklines; -PUBLIC int prefix_blankline_requested; -PUBLIC int postfix_blankline_requested; -PUBLIC int break_comma; /* when true and not in parens, - break after a comma */ -PUBLIC int btype_2; /* when true, brace should be - on same line as if, while, - etc */ -PUBLIC long case_ind; /* indentation level to be used - for a "case n:" */ -PUBLIC int code_lines; /* count of lines with code */ -PUBLIC int had_eof; /* set to true when input is - exhausted */ -PUBLIC int line_no; /* the current line number. */ -PUBLIC int max_col; /* the maximum allowable line - length */ -PUBLIC int verbose; /* when true, non-essential - error messages are printed */ -PUBLIC int cuddle_else; /* true if else should cuddle - up to '}' */ -PUBLIC int star_comment_cont; /* true iff comment - continuation lines should - have stars at the beginning - of each line. */ -PUBLIC int del_on_bl; /* comment_delimiter_on_blanklin - e */ -PUBLIC int troff; /* true iff were generating - troff input */ -PUBLIC int proc_str_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) */ -PUBLIC int proc_calls_space; /* If true, procedure calls - look like: foo(bar) rather - than foo (bar) */ -PUBLIC int format_col1_comments; /* If comments which start in - column 1 are to be magically - reformatted (just like - comments that begin in later - columns) */ -PUBLIC int inhibit_formatting; /* true if INDENT OFF is in - effect */ -PUBLIC int suppress_blanklines; /* set iff following blanklines - should be suppressed */ -PUBLIC int continuation_indent; /* set to the indentation - between the edge of code and - continuation lines */ -PUBLIC int lineup_to_parens; /* if true, continued code - within parens will be lined - up to the open paren */ -PUBLIC int Bill_Shannon; /* true iff a blank should - always be inserted after - sizeof */ -PUBLIC int bl_at_proctop; /* This is vaguely similar to - blanklines_after_declarations - 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 */ -PUBLIC int bk_max_col; -PUBLIC int ex_expr_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 */ - -/* -troff font state information */ - -struct fstate -{ - char font[4]; - char size; - int allcaps; -}; - -PUBLIC struct fstate - keywordf, /* keyword font */ - stringf, /* string font */ - boxcomf, /* Box comment font */ - blkcomf, /* Block comment font */ - scomf, /* Same line comment font */ - bodyf; /* major body font */ - - -#define STACKSIZE 150 - -PUBLIC struct parser_state -{ - int last_token; - struct fstate cfont; /* Current font */ - int p_stack[STACKSIZE]; /* this is the parsers stack */ - int il[STACKSIZE]; /* this stack stores - indentation levels */ - long cstk[STACKSIZE]; /* 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 / * */ - int comment_delta, n_comment_delta; - int cast_mask; /* indicates which close parens - close off casts */ - int sizeof_mask; /* indicates which close parens - close off sizeof''s */ - 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 coment 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 stmts */ - 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 its_a_keyword; - int sizeof_keyword; - int dumped_decl_indent; - int case_indent; /* The distance to indent case - labels from the switch - statement */ - int in_par_decl; - int indent_parameters; - int tos; /* pointer to top of stack */ - char procname[100]; /* The name of the current - procedure */ - int just_saw_decl; -} ps; - -PUBLIC int ifdef_level; -PUBLIC struct parser_state state_stack[5]; -PUBLIC struct parser_state match_state[5]; diff --git a/commands/indent/indent.c b/commands/indent/indent.c deleted file mode 100644 index 2c36d5775..000000000 --- a/commands/indent/indent.c +++ /dev/null @@ -1,1374 +0,0 @@ -/** - * Copyright (c) 1985 Sun Microsystems, Inc. - * Copyright (c) 1980 The Regents of the University of California. - * Copyright (c) 1976 Board of Trustees of the University of Illinois. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley, the University of Illinois, - * Urbana, and Sun Microsystems, Inc. The name of either University - * or Sun Microsystems may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -/* ported to MINIX by: Robert R. Hall */ - -#define _POSIX_SOURCE 1 -#define PUBLIC -#define NAME_SIZE _POSIX_NAME_MAX - -#include -#include -#include -#include -#include -#include -#include -#include -#include "globs.h" -#include "codes.h" -#include "proto.h" - -char *in_name = "Standard Input"; /* will always point to - name of input file */ -char *out_name = "Standard Output"; /* will always point to - name of output file */ -char bakfile[60]; - -int main(argc, argv) - int argc; - char **argv; -{ - - extern int found_err; /* flag set in diag() on error */ - int dec_ind; /* current indentation for - declarations */ - int di_stack[20]; /* a stack of structure - indentation levels */ - int flushed_nl; /* used when buffering up - comments to remember that a - newline was passed over */ - int force_nl; /* when true, code must be - broken */ - int hd_type; /* used to store type of stmt - for if (...), for (...), etc */ - register 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 - expressin of if(...), - while(...), etc. */ - int squest; /* when this is positive, we - have seen a ? without the - matching : in a ?: - construct */ - register char *t_ptr; /* used for copying tokens */ - int type_code; /* the type of token, returned - by lexi */ - - int last_else = 0; /* true iff last keyword was an - else */ - - - /*-----------------------------------------------*\ - | INITIALIZATION | - \*-----------------------------------------------*/ - - - 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); - labbuf = (char *) malloc(bufsize); - codebuf = (char *) malloc(bufsize); - l_com = combuf + bufsize - 5; - l_lab = labbuf + bufsize - 5; - l_code = codebuf + 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 */ - s_lab = e_lab = labbuf + 1; - s_code = e_code = codebuf + 1; - s_com = e_com = combuf + 1; - - 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 = 0; - bp_save = 0; - be_save = 0; - - output = 0; - - - - /*--------------------------------------------------*\ - | COMMAND LINE SCAN | - \*--------------------------------------------------*/ - -#ifdef undef - max_col = 78; /* -l78 */ - lineup_to_parens = 1; /* -lp */ - 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.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_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; - set_defaults(); - if (i >= argc) - set_profile(); - - 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 == 0) - { /* we must have the input file */ - in_name = argv[i]; /* remember name of input file */ - input = fopen(in_name, "r"); - if (input == 0) - { /* check for open error */ - fprintf(stderr, "indent: can't open %s\n", argv[i]); - exit(1); - } - continue; - } else if (output == 0) - { /* 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 */ - fprintf(stderr, "indent: input and output files must be different\n"); - exit(1); - } - output = fopen(out_name, "w"); - if (output == 0) - { /* check for create error */ - fprintf(stderr, "indent: can't create %s\n", argv[i]); - exit(1); - } - continue; - } - fprintf(stderr, "indent: unknown parameter: %s\n", argv[i]); - exit(1); - } else - set_option(argv[i]); - } /* end of for */ - if (input == 0) - { - fprintf(stderr, "indent: usage: indent file [ outfile ] [ options ]\n"); - exit(1); - } - if (output == 0) - if (troff) - output = stdout; - else - { - out_name = in_name; - bakcopy(); - } - if (ps.com_ind <= 1) - ps.com_ind = 2; /* dont put normal comments - before column 2 */ - if (troff) - { - if (bodyf.font[0] == 0) - parsefont(&bodyf, "R"); - if (scomf.font[0] == 0) - parsefont(&scomf, "I"); - if (blkcomf.font[0] == 0) - blkcomf = scomf, blkcomf.size += 2; - if (boxcomf.font[0] == 0) - boxcomf = blkcomf; - if (stringf.font[0] == 0) - parsefont(&stringf, "L"); - if (keywordf.font[0] == 0) - parsefont(&keywordf, "B"); - writefdef(&bodyf, 'B'); - writefdef(&scomf, 'C'); - writefdef(&blkcomf, 'L'); - writefdef(&boxcomf, 'X'); - writefdef(&stringf, 'S'); - writefdef(&keywordf, 'K'); - } - if (bk_max_col <= 0) - bk_max_col = max_col; - 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; - fill_buffer(); /* get first batch of stuff - into input buffer */ - - parse(semicolon); - { - register char *p = buf_ptr; - register col = 1; - - while (1) - { - if (*p == ' ') - col++; - else if (*p == '\t') - col = ((col - 1) & ~7) + 9; - else - break; - p++; - }; - if (col > ps.ind_size) - ps.ind_level = ps.i_l_follow = col / ps.ind_size; - } - if (troff) - { - register char *p = in_name, *beg = in_name; - - while (*p) - if (*p++ == '/') - beg = p; - fprintf(output, ".Fn \"%s\"\n", beg); - } - /* START OF MAIN LOOP */ - - while (1) - { /* this is the main loop. it - will go until we reach eof */ - int is_procname; - - type_code = lexi(); /* lexi reads one token. The - actual characters read are - stored in "token". lexi - returns a code indicating - the type of token */ - is_procname = ps.procname[0]; - - /* The following code moves everything 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. */ - - flushed_nl = false; - while (ps.search_brace) - { /* if we scanned an if(), - while(), etc., we might need - to copy stuff into a buffer - we must loop, copying stuff - into save_com, until we find - the start of the stmt which - follows the if, or whatever */ - switch (type_code) - { - case newline: - ++line_no; - flushed_nl = true; - case form_feed: - break; /* form feeds and newlines - found here will be ignored */ - - case lbrace: /* this is a brace that starts - the compound stmt */ - if (sc_end == 0) - { /* ignore buffering if a - comment wasnt stored up */ - ps.search_brace = false; - goto check_type; - } - if (btype_2) - { - save_com[0] = '{'; /* we either want to put the - brace right after the if */ - goto sw_buffer; /* go to common code to get out - of this loop */ - } -/* - * Something is buffered up in save_com, and -bl processing is in effect. - * Add the brace after the comment so it will come out on the next line. - */ - flushed_nl = 0; /* comment can start on the same line */ - *sc_end++ = '\n'; /* break line after comment */ - *sc_end++ = '{'; - goto sw_buffer; - - case comment: /* we have a comment, so we - must copy it into the buffer */ - if (!flushed_nl || sc_end != 0) - { - if (sc_end == 0) - { /* if this is the first - comment, we must set up the - buffer */ - save_com[0] = save_com[1] = ' '; - sc_end = &(save_com[2]); - } else - { - *sc_end++ = '\n'; /* add newline between comments */ - *sc_end++ = ' '; - --line_no; - } - *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 */ - diag(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; - } - default: /* it is the start of a normal - statment */ - if (flushed_nl) /* if we flushed a newline, - make sure it is put back */ - force_nl = true; - if ((type_code == sp_paren && *token == 'i' - && last_else && ps.else_if) - || (type_code == sp_nparen && *token == 'e' - && e_code != s_code && e_code[-1] == '}')) - force_nl = false; - - if (sc_end == 0) - { /* ignore buffering if comment - wasnt saved up */ - ps.search_brace = false; - goto check_type; - } - 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 nl is read from the - buffer */ - *sc_end++ = '\n'; - *sc_end++ = ' '; - if (verbose && !flushed_nl) /* print error msg if - the line was not - already broken */ - diag(0, "Line broken"); - flushed_nl = false; - } - for (t_ptr = token; *t_ptr; ++t_ptr) - *sc_end++ = *t_ptr; /* copy token into temp buffer */ - ps.procname[0] = 0; - - 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 = 0; - break; - } /* end of switch */ - if (type_code != 0) /* we must make this check, - just in case there was an - unexpected EOF */ - type_code = lexi(); /* read another token */ - /* if (ps.search_brace) ps.procname[0] = 0; */ - if ((is_procname = ps.procname[0]) && flushed_nl - && !proc_str_line && ps.in_decl - && type_code == ident) - flushed_nl = 0; - } /* 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 */ - diag(1, "Stuff missing from end of file."); - - if (verbose) - { - printf("There were %d output lines and %d comments\n", - ps.out_lines, ps.out_coms); - printf("(Lines with comments)/(Lines with code): %6d\n", - 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)) - { - /* we should force a broken line here */ - if (verbose && !flushed_nl) - diag(0, "Line broken"); - flushed_nl = false; - 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 */ - *e_code++ = ' '; - for (t_ptr = s_com; *t_ptr; ++t_ptr) - { - if (e_code >= l_code) - { - register nsize = l_code - s_code + 400; - codebuf = (char *) realloc(codebuf, nsize); - e_code = codebuf + (e_code - s_code) + 1; - l_code = codebuf + nsize - 5; - s_code = codebuf + 1; - } - *e_code++ = *t_ptr; - } - *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 | - \*-----------------------------------------------------*/ - if (e_code >= l_code) - { - register nsize = l_code - s_code + 400; - codebuf = (char *) realloc(codebuf, nsize); - e_code = codebuf + (e_code - s_code) + 1; - l_code = codebuf + nsize - 5; - s_code = codebuf + 1; - } - 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) - { - dump_line(); - ps.want_blank = false; - } - ++line_no; /* keep track of input line - number */ - break; - - case lparen: /* got a '(' or '[' */ - ++ps.p_l_follow; /* count parens to make Healy - happy */ - if (ps.want_blank && *token != '[' && - (ps.last_token != ident || proc_calls_space - || (ps.its_a_keyword && (!ps.sizeof_keyword || Bill_Shannon)))) - *e_code++ = ' '; - if (ps.in_decl && !ps.block_init) - if (troff && !ps.dumped_decl_indent && !is_procname && ps.last_token == decl) - { - ps.dumped_decl_indent = 1; - sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); - e_code += strlen(e_code); - } else - { - while ((e_code - s_code) < dec_ind) - { - if (e_code >= l_code) - { - register nsize = l_code - s_code + 400; - codebuf = (char *) realloc(codebuf, nsize); - e_code = codebuf + (e_code - s_code) + 1; - l_code = codebuf + nsize - 5; - s_code = codebuf + 1; - } - *e_code++ = ' '; - } - *e_code++ = token[0]; - } - else - *e_code++ = token[0]; - ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code; - if (sp_sw && ps.p_l_follow == 1 && ex_expr_indent - && ps.paren_indents[0] < 2 * ps.ind_size) - ps.paren_indents[0] = 2 * ps.ind_size; - ps.want_blank = false; - 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 */ - } - if (ps.sizeof_keyword) - ps.sizeof_mask |= 1 << ps.p_l_follow; - break; - - case rparen: /* got a ')' or ']' */ - if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask) - { - ps.last_u_d = true; - ps.cast_mask &= (1 << ps.p_l_follow) - 1; - } - ps.sizeof_mask &= (1 << ps.p_l_follow) - 1; - if (--ps.p_l_follow < 0) - { - ps.p_l_follow = 0; - diag(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]; - ps.want_blank = true; - - 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 */ - break; - - case unary_op: /* this could be any unary - operation */ - if (ps.want_blank) - *e_code++ = ' '; - - if (troff && !ps.dumped_decl_indent && ps.in_decl && !is_procname) - { - sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); - ps.dumped_decl_indent = 1; - e_code += strlen(e_code); - } else - { - char *res = token; - - if (ps.in_decl && !ps.block_init) - { /* if this is a unary op in a - declaration, we should - indent this token */ - for (i = 0; token[i]; ++i); /* find length of token */ - while ((e_code - s_code) < (dec_ind - i)) - { - if (e_code >= l_code) - { - register nsize = l_code - s_code + 400; - codebuf = (char *) realloc(codebuf, nsize); - e_code = codebuf + (e_code - s_code) + 1; - l_code = codebuf + nsize - 5; - s_code = codebuf + 1; - } - *e_code++ = ' '; /* pad it */ - } - } - if (troff && token[0] == '-' && token[1] == '>') - res = "\\(->"; - for (t_ptr = res; *t_ptr; ++t_ptr) - { - if (e_code >= l_code) - { - register nsize = l_code - s_code + 400; - codebuf = (char *) realloc(codebuf, nsize); - e_code = codebuf + (e_code - s_code) + 1; - l_code = codebuf + nsize - 5; - s_code = codebuf + 1; - } - *e_code++ = *t_ptr; - } - } - ps.want_blank = false; - break; - - case binary_op: /* any binary operation */ - if (ps.want_blank) - *e_code++ = ' '; - { - char *res = token; - - if (troff) - switch (token[0]) - { - case '<': - if (token[1] == '=') - res = "\\(<="; - break; - case '>': - if (token[1] == '=') - res = "\\(>="; - break; - case '!': - if (token[1] == '=') - res = "\\(!="; - break; - case '|': - if (token[1] == '|') - res = "\\(br\\(br"; - else if (token[1] == 0) - res = "\\(br"; - break; - } - for (t_ptr = res; *t_ptr; ++t_ptr) - { - if (e_code >= l_code) - { - register nsize = l_code - s_code + 400; - codebuf = (char *) realloc(codebuf, nsize); - e_code = codebuf + (e_code - s_code) + 1; - l_code = codebuf + nsize - 5; - s_code = codebuf + 1; - } - *e_code++ = *t_ptr; /* move the operator */ - } - } - 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_decl) - { - *e_code++ = ':'; - ps.want_blank = false; - break; - } - ps.in_stmt = false; /* seeing a label does not - imply we are in a stmt */ - for (t_ptr = s_code; *t_ptr; ++t_ptr) - *e_lab++ = *t_ptr; /* turn everything so far into - a label */ - e_code = s_code; - *e_lab++ = ':'; - *e_lab++ = ' '; - *e_lab = '\0'; - - 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 ';' */ - ps.in_or_st = false; /* we are not in an - initialization or structure - declaration */ - scase = false; /* these will only need - resetting in a error */ - squest = 0; - if (ps.last_token == rparen) - ps.in_par_decl = 0; - ps.cast_mask = 0; - ps.sizeof_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) - while ((e_code - s_code) < (dec_ind - 1)) - { - if (e_code >= l_code) - { - register nsize = l_code - s_code + 400; - codebuf = (char *) realloc(codebuf, nsize); - e_code = codebuf + (e_code - s_code) + 1; - l_code = codebuf + nsize - 5; - s_code = codebuf + 1; - } - *e_code++ = ' '; - } - - 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 */ - diag(1, "Unbalanced parens"); - ps.p_l_follow = 0; - if (sp_sw) - { /* this is a check for a 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 a 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) - { - dump_line(); - ps.want_blank = false; - } else if (ps.in_par_decl && !ps.in_or_st) - { - ps.i_l_follow = 0; - dump_line(); - ps.want_blank = false; - } - } - if (ps.in_par_decl) - prefix_blankline_requested = 0; - - if (ps.p_l_follow > 0) - { /* check for preceeding - unbalanced parens */ - diag(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; - /* ? dec_ind = 0; */ - } else - { - ps.decl_on_line = false; /* we cant be in the middle of - a declaration, so dont do - special indentation of - comments */ - if (bl_at_proctop - && ps.in_par_decl) - postfix_blankline_requested = 1; - ps.in_par_decl = 0; - } - 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. */ - diag(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) - diag(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_par_decl) - 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.il[ps.tos] >= ps.ind_level; - if (ps.tos <= 1 && bl_a_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) - diag(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) - diag(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 decl: /* we have a declaration type - (int, register, etc.) */ - parse(decl); /* let parser worry about - indentation */ - if (ps.last_token == rparen && ps.tos <= 1) - { - ps.in_par_decl = 1; - if (s_code != e_code) - { - dump_line(); - ps.want_blank = 0; - } - } - if (ps.in_par_decl && ps.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 = true; - 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 */ - - /* dec_ind = e_code - s_code + (ps.decl_indent>i ? - ps.decl_indent : i); */ - dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i; - goto copy_id; - - case ident: /* got an identifier or - constant */ - if (ps.in_decl) - { /* if we are in a declaration, - we must indent identifier */ - if (ps.want_blank) - *e_code++ = ' '; - ps.want_blank = false; - if (is_procname == 0 || !proc_str_line) - { - if (!ps.block_init) - if (troff && !ps.dumped_decl_indent) - { - sprintf(e_code, "\n.De %dp+\200p\n", dec_ind * 7); - ps.dumped_decl_indent = 1; - e_code += strlen(e_code); - } else - while ((e_code - s_code) < dec_ind) - { - if (e_code >= l_code) - { - register nsize = l_code - s_code + 400; - codebuf = (char *) realloc(codebuf, nsize); - e_code = codebuf + (e_code - s_code) + 1; - l_code = codebuf + nsize - 5; - s_code = codebuf + 1; - } - *e_code++ = ' '; - } - } else - { - if (dec_ind && s_code != e_code) - dump_line(); - dec_ind = 0; - 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: - if (ps.want_blank) - *e_code++ = ' '; - if (troff && ps.its_a_keyword) - { - e_code = chfont(&bodyf, &keywordf, e_code); - for (t_ptr = token; *t_ptr; ++t_ptr) - { - if (e_code >= l_code) - { - register nsize = l_code - s_code + 400; - codebuf = (char *) realloc(codebuf, nsize); - e_code = codebuf + (e_code - s_code) + 1; - l_code = codebuf + nsize - 5; - s_code = codebuf + 1; - } - *e_code++ = keywordf.allcaps && islower(*t_ptr) - ? toupper(*t_ptr) : *t_ptr; - } - e_code = chfont(&keywordf, &bodyf, e_code); - } else - for (t_ptr = token; *t_ptr; ++t_ptr) - { - if (e_code >= l_code) - { - register nsize = l_code - s_code + 400; - codebuf = (char *) realloc(codebuf, nsize); - e_code = codebuf + (e_code - s_code) + 1; - l_code = codebuf + nsize - 5; - s_code = codebuf + 1; - } - *e_code++ = *t_ptr; - } - ps.want_blank = true; - 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 && is_procname == 0 && !ps.block_init) - while ((e_code - s_code) < (dec_ind - 1)) - { - if (e_code >= l_code) - { - register nsize = l_code - s_code + 400; - codebuf = (char *) realloc(codebuf, nsize); - e_code = codebuf + (e_code - s_code) + 1; - l_code = codebuf + nsize - 5; - s_code = codebuf + 1; - } - *e_code++ = ' '; - } - - *e_code++ = ','; - if (ps.p_l_follow == 0) - { - if (ps.block_init_level <= 0) - ps.block_init = 0; - if (break_comma && !ps.leave_comma) - force_nl = true; - } - break; - - case preesc: /* got the character '#' */ - if ((s_com != e_com) || - (s_lab != e_lab) || - (s_code != e_code)) - dump_line(); - *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 != '\n' || in_comment) - { - if (e_lab >= l_lab) - { - register nsize = l_lab - s_lab + 400; - labbuf = (char *) realloc(labbuf, nsize); - e_lab = labbuf + (e_lab - s_lab) + 1; - l_lab = labbuf + nsize - 5; - s_lab = labbuf + 1; - } - *e_lab = *buf_ptr++; - if (buf_ptr >= buf_end) - fill_buffer(); - switch (*e_lab++) - { - case BACKSLASH: - if (troff) - *e_lab++ = 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 == 0) - { /* comment on preprocessor line */ - if (sc_end == 0) /* if this is the first - comment, we must set up the - buffer */ - sc_end = &(save_com[0]); - else - { - *sc_end++ = '\n'; /* add newline between comments */ - *sc_end++ = ' '; - --line_no; - } - memcpy(sc_end, s_lab + com_start, com_end - com_start); - sc_end += com_end - com_start; - if (sc_end >= &save_com[sc_size]) - abort(); - 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 = 0; - } - *e_lab = '\0'; /* null terminate line */ - ps.pcase = false; - } - - if (strncmp(s_lab, "#if", 3) == 0) - { - if (bl_around) - { - register c; - prefix_blankline_requested++; - while ((c = getc(input)) == '\n'); - ungetc(c, input); - } - if (ifdef_level < sizeof state_stack / sizeof state_stack[0]) - { - match_state[ifdef_level].tos = -1; - state_stack[ifdef_level++] = ps; - } else - diag(1, "#if stack overflow"); - } else if (strncmp(s_lab, "#else", 5) == 0) - if (ifdef_level <= 0) - diag(1, "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) - diag(1, "Unmatched #endif"); - else - { - ifdef_level--; - -#ifdef undef - /* This match needs to be more intelligent before the - message is useful */ - if (match_state[ifdef_level].tos >= 0 - && bcmp(&ps, &match_state[ifdef_level], sizeof ps)) - diag(0, "Syntactically inconsistant #ifdef alternatives."); -#endif - } - if (bl_around) - { - postfix_blankline_requested++; - n_real_blanklines = 0; - } - } - break; /* subsequent processing of the - newline character will cause - the line to be printed */ - - case comment: /* we have gotten a / * this is - a biggie */ - if (flushed_nl) - { /* we should force a broken - line here */ - flushed_nl = false; - dump_line(); - ps.want_blank = false; /* dont insert blank at line - start */ - force_nl = false; - } - 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 - */ -void bakcopy() -{ - int n, bakchn; - char buff[8 * 1024]; - register 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.BAK", p); - if (strlen(p) >= NAME_SIZE) *bakfile ^= 040; /* toggle char */ - - /* copy in_name to backup file */ - bakchn = creat(bakfile, 0600); - if (bakchn < 0) - { - fprintf(stderr, "indent: can't create backup file \"%s\"\n", bakfile); - exit(1); - } - while (n = read(fileno(input), buff, sizeof buff)) - if (write(bakchn, buff, n) != n) - { - fprintf(stderr, "indent: error writing backup file \"%s\"\n", - bakfile); - exit(1); - } - if (n < 0) - { - fprintf(stderr, "indent: error reading input file \"%s\"\n", in_name); - exit(1); - } - close(bakchn); - fclose(input); - - /* re-open backup file as the input file */ - input = fopen(bakfile, "r"); - if (input == 0) - { - fprintf(stderr, "indent: can't re-open backup file\n"); - exit(1); - } - /* now the original input file will be the output */ - output = fopen(in_name, "w"); - if (output == 0) - { - fprintf(stderr, "indent: can't create %s\n", in_name); - unlink(bakfile); - exit(1); - } -} diff --git a/commands/indent/indent.pro b/commands/indent/indent.pro deleted file mode 100644 index f1784e604..000000000 --- a/commands/indent/indent.pro +++ /dev/null @@ -1 +0,0 @@ --bap -bbb -br -ncdb -cli0.5 -di1 -lp -npsl -nfc1 -nip diff --git a/commands/indent/io.c b/commands/indent/io.c deleted file mode 100644 index 67a2781fb..000000000 --- a/commands/indent/io.c +++ /dev/null @@ -1,636 +0,0 @@ -/** - * Copyright (c) 1985 Sun Microsystems, Inc. - * Copyright (c) 1980 The Regents of the University of California. - * Copyright (c) 1976 Board of Trustees of the University of Illinois. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley, the University of Illinois, - * Urbana, and Sun Microsystems, Inc. The name of either University - * or Sun Microsystems may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#define PUBLIC extern -#include -#include -#include -#include "globs.h" -#include "proto.h" - - -int comment_open; -static paren_target; - -void dump_line() -{ /* 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 */ - register int cur_col, target_col; - static not_first_line; - - if (ps.procname[0]) - { - if (troff) - { - if (comment_open) - { - comment_open = 0; - fprintf(output, ".*/\n"); - } - fprintf(output, ".Pr \"%s\"\n", ps.procname); - } - 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_opt_bl) - { - 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--; - cur_col = pad_output(1, label_target()); - 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 */ - register char *p; - - if (comment_open) - { - comment_open = 0; - fprintf(output, ".*/\n"); - } - target_col = code_target(); - { - register 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) - if (troff) - { - int all_here = 0; - register char *p; - - if (e_com[-1] == '/' && e_com[-2] == '*') - e_com -= 2, all_here++; - while (e_com > s_com && e_com[-1] == ' ') - e_com--; - *e_com = 0; - p = s_com; - while (*p == ' ') - p++; - if (p[0] == '/' && p[1] == '*') - p += 2, all_here++; - else if (p[0] == '*') - p += p[1] == '/' ? 2 : 1; - while (*p == ' ') - p++; - if (*p == 0) - goto inhibit_newline; - if (comment_open < 2 && ps.box_com) - { - comment_open = 0; - fprintf(output, ".*/\n"); - } - if (comment_open == 0) - { - if ('a' <= *p && *p <= 'z') - *p = *p + 'A' - 'a'; - if (e_com - p < 50 && all_here == 2) - { - register char *follow = p; - fprintf(output, "\n.nr C! \\w\1"); - while (follow < e_com) - { - switch (*follow) - { - case '\n': - putc(' ', output); - case 1: - break; - case '\\': - putc('\\', output); - default: - putc(*follow, output); - } - follow++; - } - putc(1, output); - } - fprintf(output, "\n./* %dp %d %dp\n", - ps.com_col * 7, - (s_code != e_code || s_lab != e_lab) - ps.box_com, - target_col * 7); - } - comment_open = 1 + ps.box_com; - while (*p) - { - if (*p == BACKSLASH) - putc(BACKSLASH, output); - putc(*p++, output); - } - } else - { /* print comment, if any */ - register target = ps.com_col; - register char *com_st = s_com; - - target += ps.comment_delta; - while (*com_st == '\t') - com_st++, target += 8; /* ? */ - while (target <= 0) - if (*com_st == ' ') - target++, com_st++; - else if (*com_st == '\t') - target = ((target - 1) & ~7) + 9, com_st++; - else - target = 1; - if (cur_col > target) - { /* if comment cant fit on this - line, put it on next line */ - putc('\n', output); - cur_col = 1; - ++ps.out_lines; - } - while (e_com > com_st && isspace(e_com[-1])) - e_com--; - cur_col = pad_output(cur_col, target); - if (!ps.box_com) - { - if (star_comment_cont && (com_st[1] != '*' || e_com <= com_st + 1)) - if (com_st[1] == ' ' && com_st[0] == ' ' && e_com > com_st + 1) - com_st[1] = '*'; - else - fwrite(" * ", com_st[0] == '\t' ? 2 : com_st[0] == '*' ? 1 : 3, 1, output); - } - fwrite(com_st, (int)(e_com - com_st), 1, output); - ps.comment_delta = ps.n_comment_delta; - cur_col = count_spaces(cur_col, com_st); - ++ps.com_lines; /* count lines with comments */ - } - if (ps.use_ff) - putc('\014', output); - else - putc('\n', output); -inhibit_newline: - ++ps.out_lines; - if (ps.just_saw_decl == 1 && bl_aft_decl) - { - 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) = '\0'; - ps.ind_level = ps.i_l_follow; - ps.paren_level = ps.p_l_follow; - paren_target = -ps.paren_indents[ps.paren_level - 1]; - not_first_line = 1; - return; -} - -int code_target() -{ - register target_col = ps.ind_size * ps.ind_level + 1; - - if (ps.paren_level) - if (!lineup_to_parens) - target_col += continuation_indent * ps.paren_level; - else - { - register w; - register t = paren_target; - - if ((w = count_spaces(t, s_code) - max_col) > 0 - && count_spaces(target_col, s_code) <= 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; - return target_col; -} - -int label_target() -{ - return - ps.pcase ? (int) (case_ind * ps.ind_size) + 1 - : *s_lab == '#' ? 1 - : ps.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() -{ /* this routine reads stuff - from the input */ - register char *p; - register int i; - register FILE *f = input; - - if (bp_save != 0) - { /* there is a partly filled - input buffer left */ - buf_ptr = bp_save; /* dont read anything, just - switch buffers */ - buf_end = be_save; - bp_save = be_save = 0; - if (buf_ptr < buf_end) - return; /* only return if there is - really something in this - buffer */ - } - for (p = buf_ptr = in_buffer;;) - { - if ((i = getc(f)) == EOF) - { - *p++ = ' '; - *p++ = '\n'; - had_eof = true; - break; - } - *p++ = (char)i; - if (i == '\n') - break; - } - buf_end = p; - if (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'); - } - return; -} - -/* - * 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 - * - */ -int pad_output(current, target) /* writes tabs and blanks (if - necessary) to get the - current output position up - to the target column */ - int current; /* the current column value */ - int target; /* position we want it at */ -{ - register int curr; /* internal column pointer */ - register int tcur; - - if (troff) - fprintf(output, "\\h'|%dp'", (target - 1) * 7); - else - { - if (current >= target) - return (current); /* line is already long enough */ - curr = current; - while ((tcur = ((curr - 1) & tabmask) + 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(current, buffer) -/* - * this routine figures out where the character position will be after - * printing the text in buffer starting at column "current" - */ - int current; - char *buffer; -{ - register char *buf; /* used to look thru buffer */ - register int cur; /* current character counter */ - - cur = current; - - for (buf = buffer; *buf != '\0'; ++buf) - { - switch (*buf) - { - - case '\n': - case 014: /* form feed */ - cur = 1; - break; - - case '\t': - cur = ((cur - 1) & tabmask) + tabsize + 1; - break; - - case '': /* this is a backspace */ - --cur; - break; - - default: - ++cur; - break; - } /* end of switch */ - } /* end of for loop */ - return (cur); -} - -int found_err; -void diag(level, msg, a, b) -int level; -char *msg; -int a, 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 writefdef(f, nm) - register struct fstate *f; - int nm; -{ - fprintf(output, ".ds f%c %s\n.nr s%c %d\n", - nm, f->font, nm, f->size); -} - -char * -chfont(of, nf, s) - register struct fstate *of, *nf; - char *s; -{ - if (of->font[0] != nf->font[0] - || of->font[1] != nf->font[1]) - { - *s++ = '\\'; - *s++ = 'f'; - if (nf->font[1]) - { - *s++ = '('; - *s++ = nf->font[0]; - *s++ = nf->font[1]; - } else - *s++ = nf->font[0]; - } - if (nf->size != of->size) - { - *s++ = '\\'; - *s++ = 's'; - if (nf->size < of->size) - { - *s++ = '-'; - *s++ = (char)'0' + of->size - nf->size; - } else - { - *s++ = '+'; - *s++ = (char)'0' + nf->size - of->size; - } - } - return s; -} - - -void parsefont(f, s0) - register struct fstate *f; - char *s0; -{ - register char *s = s0; - int sizedelta = 0; - memset(f, '\0', sizeof *f); - while (*s) - { - if (isdigit(*s)) - f->size = f->size * 10 + *s - '0'; - else if (isupper(*s)) - if (f->font[0]) - f->font[1] = *s; - else - f->font[0] = *s; - else if (*s == 'c') - f->allcaps = 1; - else if (*s == '+') - sizedelta++; - else if (*s == '-') - sizedelta--; - else - { - fprintf(stderr, "indent: bad font specification: %s\n", s0); - exit(1); - } - s++; - } - if (f->font[0] == 0) - f->font[0] = 'R'; - if (bodyf.size == 0) - bodyf.size = 11; - if (f->size == 0) - f->size = bodyf.size + sizedelta; - else if (sizedelta > 0) - f->size += bodyf.size; - else - f->size = bodyf.size - f->size; -} diff --git a/commands/indent/lexi.c b/commands/indent/lexi.c deleted file mode 100644 index 6cf42c8c0..000000000 --- a/commands/indent/lexi.c +++ /dev/null @@ -1,571 +0,0 @@ -/** - * Copyright (c) 1985 Sun Microsystems, Inc. - * Copyright (c) 1980 The Regents of the University of California. - * Copyright (c) 1976 Board of Trustees of the University of Illinois. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley, the University of Illinois, - * Urbana, and Sun Microsystems, Inc. The name of either University - * or Sun Microsystems may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -/* - * 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. - */ - -#define PUBLIC extern -#include -#include -#include "globs.h" -#include "codes.h" -#include "proto.h" - -#define alphanum 1 -#define opchar 3 - -struct templ -{ - char *rwd; - int rwcode; -}; - -struct templ specials[100] = -{ - "switch", 1, - "case", 2, - "break", 0, - "struct", 3, - "union", 3, - "enum", 3, - "default", 2, - "int", 4, - "char", 4, - "float", 4, - "double", 4, - "long", 4, - "short", 4, - "typedef", 4, - "unsigned", 4, - "register", 4, - "static", 4, - "global", 4, - "extern", 4, - "void", 4, - "goto", 0, - "return", 0, - "if", 5, - "while", 5, - "for", 5, - "else", 6, - "do", 6, - "sizeof", 7, - 0, 0 -}; - -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 -}; - - - - -int -lexi() -{ - register char *tok; /* local pointer to next char - in token */ - int unary_delim; /* this is set to 1 if the - current token - - forces a following operator to - be unary */ - static int last_code; /* the last token type returned */ - static int l_struct; /* set to 1 if the last token - was 'struct' */ - int code; /* internal code to be returned */ - char qchar; /* the delimiter character for - a string */ - - tok = token; /* point to start of place to - save token */ - unary_delim = false; - ps.col_1 = ps.last_nl; /* tell world that this token - started in column 1 iff the - last thing scanned was nl */ - ps.last_nl = false; - - while (*buf_ptr == ' ' || *buf_ptr == '\t') - { /* get rid of blanks */ - ps.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] == alphanum || (buf_ptr[0] == '.' && isdigit(buf_ptr[1]))) - { - /* we have a character or number */ - register char *j; /* used for searching thru list - of - - reserved words */ - register struct templ *p; - - if (isdigit(*buf_ptr) || (buf_ptr[0] == '.' && isdigit(buf_ptr[1]))) - { - int seendot = 0, seenexp = 0; - if (*buf_ptr == '0' && - (buf_ptr[1] == 'x' || buf_ptr[1] == 'X')) - { - *tok++ = *buf_ptr++; - *tok++ = *buf_ptr++; - while (isxdigit(*buf_ptr)) - *tok++ = *buf_ptr++; - } else - while (1) - { - if (*buf_ptr == '.') - if (seendot) - break; - else - seendot++; - *tok++ = *buf_ptr++; - if (!isdigit(*buf_ptr) && *buf_ptr != '.') - if ((*buf_ptr != 'E' && *buf_ptr != 'e') || seenexp) - break; - else - { - seenexp++; - seendot++; - *tok++ = *buf_ptr++; - if (*buf_ptr == '+' || *buf_ptr == '-') - *tok++ = *buf_ptr++; - } - } - if (*buf_ptr == 'L' || *buf_ptr == 'l') - *tok++ = *buf_ptr++; - } else - while (chartype[*buf_ptr] == alphanum) - { /* copy it over */ - *tok++ = *buf_ptr++; - if (buf_ptr >= buf_end) - fill_buffer(); - } - *tok++ = '\0'; - while (*buf_ptr == ' ' || *buf_ptr == '\t') - { /* get rid of blanks */ - if (++buf_ptr >= buf_end) - fill_buffer(); - } - ps.its_a_keyword = false; - ps.sizeof_keyword = false; - if (l_struct) - { /* if last token was 'struct', - then this token should be - treated as a declaration */ - l_struct = false; - last_code = ident; - ps.last_u_d = true; - return (decl); - } - ps.last_u_d = false; /* Operator after indentifier - is binary */ - last_code = ident; /* Remember that this is the - code we will return */ - - /* This loop will check if the token is a keyword. */ - for (p = specials; (j = p->rwd) != 0; p++) - { - tok = token; /* point at scanned token */ - if (*j++ != *tok++ || *j++ != *tok++) - continue; /* This test depends on the - fact that identifiers are - always at least 1 character - long (ie. the first two - bytes of the identifier are - always meaningful) */ - if (tok[-1] == 0) - break; /* If its a one-character - identifier */ - while (*tok++ == *j) - if (*j++ == 0) - goto found_keyword; /* I wish that C had a - multi-level break... */ - } - if (p->rwd) - { /* we have a keyword */ - found_keyword: - ps.its_a_keyword = true; - ps.last_u_d = true; - switch (p->rwcode) - { - case 1: /* it is a switch */ - return (swstmt); - case 2: /* a case or default */ - return (casestmt); - - case 3: /* a "struct" */ - if (ps.p_l_follow) - break; /* inside parens: cast */ - l_struct = true; - - /* Next time around, we will want to know that we have had - a 'struct' */ - case 4: /* one of the declaration - keywords */ - if (ps.p_l_follow) - { - ps.cast_mask |= 1 << ps.p_l_follow; - break; /* inside parens: cast */ - } - last_code = decl; - return (decl); - - case 5: /* if, while, for */ - return (sp_paren); - - case 6: /* do, else */ - return (sp_nparen); - - case 7: - ps.sizeof_keyword = true; - default: /* all others are treated like - any other identifier */ - return (ident); - } /* end of switch */ - } /* end of if (found_it) */ - if (*buf_ptr == '(' && ps.tos <= 1 && ps.ind_level == 0) - { - register char *tp = buf_ptr; - while (tp < buf_end) - if (*tp++ == ')' && *tp == ';') - goto not_proc; - strncpy(ps.procname, token, sizeof ps.procname - 1); - ps.in_par_decl = 1; - 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 */ - if (((*buf_ptr == '*' && buf_ptr[1] != '=') || isalpha(*buf_ptr) || *buf_ptr == '_') - && !ps.p_l_follow - && !ps.block_init - && (ps.last_token == rparen || ps.last_token == semicolon || - ps.last_token == decl || - ps.last_token == lbrace || ps.last_token == rbrace)) - { - ps.its_a_keyword = true; - ps.last_u_d = true; - last_code = decl; - return decl; - } - if (last_code == decl) /* if this is a declared - variable, then following - sign is unary */ - ps.last_u_d = true; /* will make "int a -1" work */ - last_code = ident; - return (ident); /* the ident is not in the list */ - } /* end of procesing for alpanum - character */ - /* l l l Scan a non-alphanumeric token */ - *tok++ = *buf_ptr; /* if it is only a - one-character token, it is - moved here */ - *tok = '\0'; - if (++buf_ptr >= buf_end) - fill_buffer(); - - switch (*token) - { - case '\n': - unary_delim = ps.last_u_d; - ps.last_nl = true; /* remember that we just had a - newline */ - code = (had_eof ? 0 : newline); - - /* if data has been exausted, the newline is a dummy, and we - should return code to stop */ - break; - - case '\'': /* start of quoted character */ - case '"': /* start of string */ - qchar = *token; - if (troff) - { - tok[-1] = '`'; - if (qchar == '"') - *tok++ = '`'; - tok = chfont(&bodyf, &stringf, tok); - } - do - { /* copy the string */ - while (1) - { /* move one character or - [/] */ - if (*buf_ptr == '\n') - { - printf("%d: Unterminated literal\n", line_no); - goto stop_lit; - } - *tok = *buf_ptr++; - if (buf_ptr >= buf_end) - fill_buffer(); - if (had_eof || ((tok - token) > (bufsize - 2))) - { - printf("Unterminated literal\n"); - ++tok; - goto stop_lit; - /* get outof literal copying loop */ - } - if (*tok == BACKSLASH) - { /* if escape, copy extra char */ - if (*buf_ptr == '\n') /* check for escaped newline */ - ++line_no; - if (troff) - { - *++tok = BACKSLASH; - if (*buf_ptr == BACKSLASH) - *++tok = BACKSLASH; - } - *++tok = *buf_ptr++; - ++tok; /* 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 (*tok++ != qchar); - if (troff) - { - tok = chfont(&stringf, &bodyf, tok - 1); - if (qchar == '"') - *tok++ = '\''; - } -stop_lit: - code = ident; - break; - - case ('('): - case ('['): - unary_delim = true; - code = lparen; - break; - - case (')'): - case (']'): - code = rparen; - break; - - case '#': - unary_delim = ps.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 (ps.in_or_st) ps.block_init = 1; */ - code = ps.block_init ? lparen : lbrace; - break; - - case ('}'): - unary_delim = true; - code = ps.block_init ? rparen : rbrace; - break; - - case 014: /* a form feed */ - unary_delim = ps.last_u_d; - ps.last_nl = true; /* remember this so we can set - 'ps.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 = (ps.last_u_d ? unary_op : binary_op); - unary_delim = true; - - if (*buf_ptr == token[0]) - { - /* check for doubled character */ - *tok++ = *buf_ptr++; - /* buffer overflow will be checked at end of loop */ - if (last_code == ident || last_code == rparen) - { - code = (ps.last_u_d ? unary_op : postop); - /* check for following ++ or -- */ - unary_delim = false; - } - } else if (*buf_ptr == '=') - /* check for operator += */ - *tok++ = *buf_ptr++; - else if (*buf_ptr == '>') - { - /* check for operator -> */ - *tok++ = *buf_ptr++; - if (!ptr_binop) - { - unary_delim = false; - code = unary_op; - ps.want_blank = false; - } - } - break; /* buffer overflow will be - checked at end of switch */ - - case '=': - if (ps.in_or_st) - ps.block_init = 1; -#ifdef undef - if (chartype[*buf_ptr] == opchar) - { /* we have two char assignment */ - tok[-1] = *buf_ptr++; - if ((tok[-1] == '<' || tok[-1] == '>') && tok[-1] == *buf_ptr) - *tok++ = *buf_ptr++; - *tok++ = '='; /* Flip =+ to += */ - *tok = 0; - } -#else - if (*buf_ptr == '=') - { /* == */ - *tok++ = '='; /* Flip =+ to += */ - buf_ptr++; - *tok = 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 == '=') - { - *tok++ = *buf_ptr; - if (++buf_ptr >= buf_end) - fill_buffer(); - } - if (*buf_ptr == '=') - *tok++ = *buf_ptr++; - code = (ps.last_u_d ? unary_op : binary_op); - unary_delim = true; - break; - - default: - if (token[0] == '/' && *buf_ptr == '*') - { - /* it is start of comment */ - *tok++ = '*'; - - if (++buf_ptr >= buf_end) - fill_buffer(); - - code = comment; - unary_delim = ps.last_u_d; - break; - } - while (*(tok - 1) == *buf_ptr || *buf_ptr == '=') - { - /* handle ||, &&, etc, and also things as in int *****i */ - *tok++ = *buf_ptr; - if (++buf_ptr >= buf_end) - fill_buffer(); - } - code = (ps.last_u_d ? unary_op : binary_op); - unary_delim = true; - - - } /* end of switch */ - if (code != newline) - { - l_struct = false; - last_code = code; - } - if (buf_ptr >= buf_end) /* check for input buffer empty */ - fill_buffer(); - ps.last_u_d = unary_delim; - *tok = '\0'; /* null terminate the token */ - return (code); -} - -/* - * Add the given keyword to the keyword table, using val as the keyword type - */ -void addkey(key, val) - char *key; - int val; -{ - register struct templ *p = specials; - while (p->rwd) - if (p->rwd[0] == key[0] && strcmp(p->rwd, key) == 0) - return; - else - p++; - if (p >= specials + sizeof specials / sizeof specials[0]) - return; /* For now, table overflows are - silently ignored */ - p->rwd = key; - p->rwcode = val; - p[1].rwd = 0; - p[1].rwcode = 0; - return; -} diff --git a/commands/indent/parse.c b/commands/indent/parse.c deleted file mode 100644 index 18d22a42e..000000000 --- a/commands/indent/parse.c +++ /dev/null @@ -1,319 +0,0 @@ -/** - * Copyright (c) 1985 Sun Microsystems, Inc. - * Copyright (c) 1980 The Regents of the University of California. - * Copyright (c) 1976 Board of Trustees of the University of Illinois. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley, the University of Illinois, - * Urbana, and Sun Microsystems, Inc. The name of either University - * or Sun Microsystems may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#define PUBLIC extern -#include "./globs.h" -#include "./codes.h" -#include "proto.h" - - - - -void parse(tk) - int 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; - /* 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 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 ..." */ - ps.i_l_follow = ps.il[ps.tos]; - 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; - 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; - } - - break; - - case elselit: /* scanned an else */ - - if (ps.p_stack[ps.tos] != ifhead) - diag(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; - } - break; - - case rbrace: /* scanned a } */ - /* stack should have or */ - if (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 - diag(1, "Stmt 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; - 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 */ - diag(1, "Unknown code to parser"); - return; - - - } /* end of switch */ - - 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; -} - -/* - * Copyright (C) 1976 by the Board of Trustees of the University of Illinois - * - * All rights reserved - * - * - * 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 | -\*----------------------------------------------*/ -void reduce() -{ - - register 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]; - - 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.p_stack[--ps.tos] = stmt; - break; - } else - return; - - default: /* anything else on top */ - return; - - } - } -} diff --git a/commands/indent/proto.h b/commands/indent/proto.h deleted file mode 100644 index 75c450999..000000000 --- a/commands/indent/proto.h +++ /dev/null @@ -1,26 +0,0 @@ -/* _PROTOTYPE( void diag, (int level,char *msg, int a, int b) ); */ -void diag(); /* HACK. should be varargs */ - -_PROTOTYPE( void set_profile, (void ) ); -_PROTOTYPE( void scan_profile, (FILE *f) ); -_PROTOTYPE( int eqin, (char *s1,char *s2) ); -_PROTOTYPE( void set_defaults, (void ) ); -_PROTOTYPE( void set_option, (char *arg) ); -_PROTOTYPE( void pr_comment, (void ) ); -_PROTOTYPE( int main, (int argc,char * *argv) ); -_PROTOTYPE( void bakcopy, (void ) ); -_PROTOTYPE( void dump_line, (void ) ); -_PROTOTYPE( int code_target, (void ) ); -_PROTOTYPE( int label_target, (void ) ); -_PROTOTYPE( void fill_buffer, (void ) ); -_PROTOTYPE( int pad_output, (int current,int target) ); -_PROTOTYPE( int count_spaces, (int current,char *buffer) ); -_PROTOTYPE( void writefdef, (struct fstate *f,int nm) ); -_PROTOTYPE( char *chfont, (struct fstate *of,struct fstate *nf,char *s) ); -_PROTOTYPE( void parsefont, (struct fstate *f,char *s0) ); -_PROTOTYPE( int lexi, (void ) ); -_PROTOTYPE( void addkey, (char *key,int val) ); -_PROTOTYPE( void makext, (char *newname,char *newext) ); -_PROTOTYPE( void parse, (int tk) ); -_PROTOTYPE( void reduce, (void ) ); - diff --git a/tools/nbsd_ports b/tools/nbsd_ports index 33357b187..f76ccebd4 100644 --- a/tools/nbsd_ports +++ b/tools/nbsd_ports @@ -3,3 +3,4 @@ lib/nbsd_libc src/lib/libc lib/nbsd_libm src/lib/libm nbsd_include src/include usr.bin/m4 src/usr.bin/m4 +usr.bin/indent src/usr.bin/indent diff --git a/usr.bin/Makefile b/usr.bin/Makefile index 98ec348f1..fff5d2ee2 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -2,6 +2,6 @@ .include -SUBDIR= m4 mkimage +SUBDIR= indent m4 mkimage .include diff --git a/usr.bin/indent/Makefile b/usr.bin/indent/Makefile new file mode 100644 index 000000000..0cc9f57de --- /dev/null +++ b/usr.bin/indent/Makefile @@ -0,0 +1,7 @@ +# $NetBSD: Makefile,v 1.6 2006/10/08 17:52:28 peter Exp $ +# from: @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= indent +SRCS= indent.c io.c lexi.c parse.c pr_comment.c args.c + +.include diff --git a/usr.bin/indent/README b/usr.bin/indent/README new file mode 100644 index 000000000..618f1de1f --- /dev/null +++ b/usr.bin/indent/README @@ -0,0 +1,97 @@ +This is the C indenter, it originally came from the University of Illinois +via some distribution tape for PDP-11 Unix. It has subsequently been +hacked upon by James Gosling @ CMU. It isn't very pretty, and really needs +to be completely redone, but it is probably the nicest C pretty printer +around. + +Further additions to provide "Kernel Normal Form" were contributed +by the folks at Sun Microsystems. + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +> From mnetor!yunexus!oz@uunet.UU.NET Wed Mar 9 15:30:55 1988 +> Date: Tue, 8 Mar 88 18:36:25 EST +> From: yunexus!oz@uunet.UU.NET (Ozan Yigit) +> To: bostic@okeeffe.berkeley.edu +> Cc: ccvaxa!willcox@uunet.UU.NET, jag@sun.com, rsalz@uunet.UU.NET +> In-Reply-To: Keith Bostic's message of Tue, 16 Feb 88 16:09:06 PST +> Subject: Re: Indent... + +Thank you for your response about indent. I was wrong in my original +observation (or mis-observation :-). UCB did keep the Illinois +copyright intact. + +The issue still is whether we can distribute indent, and if we can, which +version. David Willcox (the author) states that: + +| Several people have asked me on what basis I claim that indent is in +| the public domain. I knew I would be sorry I made that posting. +| +| Some history. Way back in 1976, the project I worked on at the +| University of Illinois Center for Advanced Computation had a huge +| battle about how to format C code. After about a week of fighting, I +| got disgusted and wrote a program, which I called indent, to reformat C +| code. It had a bunch of different options that would let you format +| the output the way you liked. In particular, all of the different +| formats being championed were supported. +| +| It was my first big C program. It was ugly. It wasn't designed, it +| just sort of grew. But it pretty much worked, and it stopped most of +| the fighting. +| +| As a matter of form, I included a University of Illinois Copyright +| notice. However, my understanding was that, since the work was done +| on an ARPA contract, it was in the public domain. +| +| Time passed. Some years later, indent showed up on one of the early +| emacs distributions. +| +| Later still, someone from UC Berlekey called the UofI and asked if +| indent was in the public domain. They wanted to include it in their +| UNIX distributions, along with the emacs stuff. I was no longer at the +| UofI, but Rob Kolstad, who was, asked me about it. I told him I didn't +| care if they used it, and since then it has been on the BSD distributions. +| +| Somewhere along the way, several other unnamed people have had their +| hands in it. It was converted to understand version 7 C. (The +| original was version 6.) It was converted from its original filter +| interface to its current "blow away the user's file" interface. +| The $HOME/.indent.pro file parsing was added. Some more formatting +| options were added. +| +| The source I have right now has two copyright notices. One is the +| original from the UofI. One is from Berkeley. +| +| I am not a lawyer, and I certainly do not understand copyright law. As +| far as I am concerned, the bulk of this program, everything covered by +| the UofI copyright, is in the public domain, and worth every penny. +| Berkeley's copyright probably should only cover their changes, and I +| don't know their feelings about sending it out. + +In any case, there appears to be noone at UofI to clarify/and change +that copyright, but I am confident (based on the statements of its +author) that the code, as it stands with its copyright, is +distributable, and will not cause any legal problems. + +Hence, the issue reduces to *which* one to distribute through +comp.sources.unix. I would suggest that with the permission of you +folks (given that you have parts copyrighted), we distribute the 4.3 +version of indent, which appears to be the most up-to-date version. I +happen to have just about every known version of indent, including the +very original submission from the author to a unix tape, later the +G-Emacs version, any 4.n version, sun version and the Unipress +version. I still think we should not have to "go-back-in-time" and +re-do all the work you people have done. + +I hope to hear from you as to what you think about this. You may of +course send 4.3 version to the moderator directly, or you can let me +know of your permission, and I will send the sources, or you can let +me know that 4.3 version is off-limits, in which case we would probably +have to revert to an older version. One way or another, I hope to get +a version of indent to comp.sources.unix. + +regards.. oz + +cc: ccvaxa!willcox + sun.com!jar + uunet!rsalz + diff --git a/usr.bin/indent/args.c b/usr.bin/indent/args.c new file mode 100644 index 000000000..3c1a9ee86 --- /dev/null +++ b/usr.bin/indent/args.c @@ -0,0 +1,461 @@ +/* $NetBSD: args.c,v 1.10 2009/04/12 11:09:49 lukem Exp $ */ + +/* + * 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. 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. + */ + +/* + * Copyright (c) 1976 Board of Trustees of the University of Illinois. + * Copyright (c) 1985 Sun Microsystems, Inc. + * 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. + */ + +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)args.c 8.1 (Berkeley) 6/6/93"; +#else +__RCSID("$NetBSD: args.c,v 1.10 2009/04/12 11:09:49 lukem Exp $"); +#endif +#endif /* not lint */ + +/* + * Argument scanning and profile reading code. Default parameters are set + * here as well. + */ + +#include +#include +#include +#include +#include "indent_globs.h" + +/* profile types */ +#define PRO_SPECIAL 1 /* special case */ +#define PRO_BOOL 2 /* boolean */ +#define PRO_INT 3 /* integer */ +#define PRO_FONT 4 /* troff font */ + +/* 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) */ + +const char *option_source = "?"; + +/* + * 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, eg -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 + }, + { + "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 + }, + { + "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 + }, + { + "fbc", PRO_FONT, 0, 0, (int *) &blkcomf + }, + { + "fbx", PRO_FONT, 0, 0, (int *) &boxcomf + }, + { + "fb", PRO_FONT, 0, 0, (int *) &bodyf + }, + { + "fc1", PRO_BOOL, true, ON, &format_col1_comments + }, + { + "fc", PRO_FONT, 0, 0, (int *) &scomf + }, + { + "fk", PRO_FONT, 0, 0, (int *) &keywordf + }, + { + "fs", PRO_FONT, 0, 0, (int *) &stringf + }, + { + "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 + }, + { + "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 + }, + { + "nfc1", PRO_BOOL, true, OFF, &format_col1_comments + }, + { + "nip", PRO_BOOL, true, OFF, &ps.indent_parameters + }, + { + "nlp", PRO_BOOL, true, OFF, &lineup_to_parens + }, + { + "npcs", PRO_BOOL, false, OFF, &proc_calls_space + }, + { + "npro", PRO_SPECIAL, 0, IGN, 0 + }, + { + "npsl", PRO_BOOL, true, OFF, &procnames_start_line + }, + { + "nps", PRO_BOOL, false, OFF, &pointer_as_binop + }, + { + "nsc", PRO_BOOL, true, OFF, &star_comment_cont + }, + { + "nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines + }, + { + "nv", PRO_BOOL, false, OFF, &verbose + }, + { + "pcs", PRO_BOOL, false, ON, &proc_calls_space + }, + { + "psl", PRO_BOOL, true, ON, &procnames_start_line + }, + { + "ps", PRO_BOOL, false, ON, &pointer_as_binop + }, + { + "sc", PRO_BOOL, true, ON, &star_comment_cont + }, + { + "sob", PRO_BOOL, false, ON, &swallow_optional_blanklines + }, + { + "st", PRO_SPECIAL, 0, STDIN, 0 + }, + { + "troff", PRO_BOOL, false, ON, &troff + }, + { + "v", PRO_BOOL, false, ON, &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(void) +{ + FILE *f; + char fname[BUFSIZ]; + static char prof[] = ".indent.pro"; + + snprintf(fname, sizeof(fname), "%s/%s", getenv("HOME"), prof); + 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"; +} + +void +scan_profile(FILE *f) +{ + int i; + char *p; + char buf[BUFSIZ]; + + while (1) { + for (p = buf; (i = getc(f)) != EOF && (*p = i) > ' '; ++p); + if (p != buf) { + *p++ = 0; + if (verbose) + printf("profile: %s\n", buf); + set_option(buf); + } else + if (i == EOF) + return; + } +} + +const char *param_start; + +int +eqin(const char *s1, const char *s2) +{ + while (*s1) { + if (*s1++ != *s2++) + return (false); + } + param_start = s2; + return (true); +} +/* + * 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_type != PRO_FONT) + *p->p_obj = p->p_default; +} + +void +set_option(char *arg) +{ + struct pro *p; + + arg++; /* ignore leading "-" */ + for (p = pro; p->p_name; p++) + if (*p->p_name == *arg && eqin(p->p_name, arg)) + goto found; + fprintf(stderr, "indent: %s: unknown parameter \"%s\"\n", option_source, arg - 1); + exit(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 == 0) + input = stdin; + if (output == 0) + output = stdout; + break; + + case KEY: + if (*param_start == 0) + goto need_param; + { + char *str; + + str = strdup(param_start); + addkey(str, 4); + } + break; + + default: + fprintf(stderr, "\ +indent: set_option: internal error: p_special %d\n", p->p_special); + exit(1); + } + 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: + fprintf(stderr, "indent: %s: ``%s'' requires a parameter\n", + option_source, arg - 1); + exit(1); + } + *p->p_obj = atoi(param_start); + break; + + case PRO_FONT: + parsefont((struct fstate *) p->p_obj, param_start); + break; + + default: + fprintf(stderr, "indent: set_option: internal error: p_type %d\n", + p->p_type); + exit(1); + } +} diff --git a/usr.bin/indent/indent.1 b/usr.bin/indent/indent.1 new file mode 100644 index 000000000..2c96c6556 --- /dev/null +++ b/usr.bin/indent/indent.1 @@ -0,0 +1,562 @@ +.\" $NetBSD: indent.1,v 1.20 2011/01/12 06:17:52 wiz Exp $ +.\" +.\" Copyright (c) 1980, 1990, 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. 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. +.\" +.\" Copyright (c) 1985 Sun Microsystems, Inc. +.\" Copyright (c) 1976 Board of Trustees of the University of Illinois. +.\" 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. +.\" +.\" from: @(#)indent.1 8.1 (Berkeley) 7/1/93 +.\" +.Dd July 1, 1993 +.Dt INDENT 1 +.Os +.Sh NAME +.Nm indent +.Nd indent and format C program source +.Sh SYNOPSIS +.Nm +.Bk -words +.Op Ar input-file Op Ar output-file +.Ek +.Bk -words +.Op Fl bacc | Fl nbacc +.Ek +.Bk -words +.Op Fl bad | Fl nbad +.Ek +.Bk -words +.Op Fl bap | Fl nbap +.Ek +.Bk -words +.Op Fl bbb | Fl nbbb +.Ek +.Bk -words +.Op Fl \&bc | Fl nbc +.Ek +.Op Fl \&bl +.Op Fl \&br +.Op Fl c Ns Ar n +.Op Fl \&cd Ns Ar n +.Bk -words +.Op Fl cdb | Fl ncdb +.Ek +.Bk -words +.Op Fl \&ce | Fl nce +.Ek +.Op Fl \&ci Ns Ar n +.Op Fl cli Ns Ar n +.Op Fl d Ns Ar n +.Op Fl \&di Ns Ar n +.Bk -words +.Op Fl fc1 | Fl nfc1 +.Ek +.Op Fl i Ns Ar n +.Bk -words +.Op Fl \&ip | Fl nip +.Ek +.Op Fl l Ns Ar n +.Op Fl \&lc Ns Ar n +.Bk -words +.Op Fl \&lp | Fl nlp +.Ek +.Op Fl npro +.Bk -words +.Op Fl pcs | Fl npcs +.Ek +.Bk -words +.Op Fl psl | Fl npsl +.Ek +.Bk -words +.Op Fl \&sc | Fl nsc +.Ek +.Bk -words +.Op Fl sob | Fl nsob +.Ek +.Op Fl \&st +.Op Fl troff +.Bk -words +.Op Fl v | Fl \&nv +.Ek +.Sh DESCRIPTION +.Nm +is a +.Tn C +program formatter. +It reformats the +.Tn C +program in the +.Ar input-file +according to the switches. +The switches which can be specified are described below. +They may appear before or after the file names. +.Pp +.Sy NOTE : +If you only specify an +.Ar input-file , +the formatting is +done `in-place', that is, the formatted file is written back into +.Ar input-file +and a backup copy of +.Ar input-file +is written in the current directory. +If +.Ar input-file +is named +.Sq Pa /blah/blah/file , +the backup file is named +.Pa file.BAK . +.Pp +If +.Ar output-file +is specified, +.Nm +checks to make sure it is different from +.Ar input-file . +.Pp +The options listed below control the formatting style imposed by +.Nm . +.Bl -tag -width Op +.It Fl bacc , nbacc +If +.Fl bacc +is specified, a blank line is forced around every conditional +compilation block. +For example, in front of every #ifdef and after every #endif. +Other blank lines surrounding such blocks will be swallowed. +Default: +.Fl nbacc . +.It Fl bad , nbad +If +.Fl bad +is specified, a blank line is forced after every block of +declarations. +Default: +.Fl nbad . +.It Fl bap , nbap +If +.Fl bap +is specified, a blank line is forced after every procedure body. +Default: +.Fl nbap . +.It Fl bbb , nbbb +If +.Fl bbb +is specified, a blank line is forced before every block comment. +Default: +.Fl nbbb . +.It Fl \&bc , nbc +If +.Fl \&bc +is specified, then a newline is forced after each comma in a declaration. +.Fl nbc +turns off this option. +Default: +.Fl \&bc . +.It Fl \&br , \&bl +Specifying +.Fl \&bl +lines up compound statements like this: +.Bd -literal -offset indent +if (...) +{ + code +} +.Ed +.Pp +Specifying +.Fl \&br +(the default) makes them look like this: +.Bd -literal -offset indent +if (...) { + code +} +.Ed +.Pp +.It Fl bs , Fl nbs +If +.Fl bs +is specified, a blank is forced after +.Ic sizeof . +Default: +.Fl nbs . +.It Fl c Ns Ar n +The column in which comments on code start. +Default: +.Fl c33 . +.It Fl cd Ns Ar n +The column in which comments on declarations start. +The default +is for these comments to start in the same column as those on code. +.It Fl cdb , ncdb +Enables (disables) the placement of comment delimiters on blank lines. +With this option enabled, comments look like this: +.Bd -literal -offset indent + /* + * this is a comment + */ +.Ed +.Pp +Rather than like this: +.Bd -literal -offset indent + /* this is a comment */ +.Ed +.Pp +This only affects block comments, not comments to the right of +code. +Default: +.Fl cdb . +.It Fl ce , nce +Enables (disables) forcing `else's to cuddle up to the immediately preceding +`}'. +Default: +.Fl \&ce . +.It Fl \&ci Ns Ar n +Sets the continuation indent to be +.Ar n . +Continuation +lines will be indented that far from the beginning of the first line of the +statement. +Parenthesized expressions have extra indentation added to +indicate the nesting, unless +.Fl \&lp +is in effect. +.Fl \&ci +defaults to the same value as +.Fl i . +.It Fl cli Ns Ar n +Causes case labels to be indented +.Ar n +tab stops to the right of the containing +.Ic switch +statement. +.Fl cli0.5 +causes case labels to be indented half a tab stop. +Default: +.Fl cli0 . +.It Fl d Ns Ar n +Controls the placement of comments which are not to the right of code. +For example, +.Fl \&d\&1 +means that such comments are placed one indentation level to the left of code. +Specifying the default +.Fl \&d\&0 +lines up these comments with the code. +See the section on comment +indentation below. +.It Fl \&di Ns Ar n +Specifies the indentation, in character positions, from a declaration keyword +to the following identifier. +Default: +.Fl di16 . +.It Fl dj , ndj +.Fl \&dj +left justifies declarations. +.Fl ndj +indents declarations the same as code. +Default: +.Fl ndj . +.It Fl \&ei , nei +Enables (disables) special +.Ic else-if +processing. +If it's enabled, an +.Ic if +following an +.Ic else +will have the same indentation as the preceding +.Ic \&if +statement. +Default: +.Fl ei . +.It Fl eei , neei +Enables (disables) extra indentation on continuation lines of +the expression part of +.Ic if +and +.Ic while +statements. +These continuation lines will be indented one extra level. +Default: +.Fl neei . +.It Fl fc1 , nfc1 +Enables (disables) the formatting of comments that start in column 1. +Often, comments whose leading `/' is in column 1 have been carefully +hand formatted by the programmer. +In such cases, +.Fl nfc1 +should be used. +Default: +.Fl fc1 . +.It Fl i Ns Ar n +The number of spaces for one indentation level. +Default: +.Fl i8 . +.It Fl \&ip , nip +Enables (disables) the indentation of parameter declarations from the left +margin. +Default: +.Fl \&ip . +.It Fl l Ns Ar n +Maximum length of an output line. +Default: +.Fl l78 . +.It Fl \&lp , nlp +Lines up code surrounded by parenthesis in continuation lines. +If a line has a left parenthesis which is not closed on that line, then +continuation lines will be lined up to start at the character +position just after the left parenthesis. +For example, here is how a piece of continued code looks with +.Fl nlp +in effect: +.Bd -literal -offset indent +p1 = first_procedure(second_procedure(p2, p3), +\ \ third_procedure(p4,p5)); +.Ed +.Pp +With +.Fl lp +in effect (the default) the code looks somewhat clearer: +.Bd -literal -offset indent +p1\ =\ first_procedure(second_procedure(p2,\ p3), +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ third_procedure(p4,p5)); +.Ed +.Pp +Inserting two more newlines we get: +.Bd -literal -offset indent +p1\ =\ first_procedure(second_procedure(p2, +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ p3), +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ third_procedure(p4 +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ p5)); +.Ed +.It Fl npro +Causes the profile files, +.Sq Pa ./.indent.pro +and +.Sq Pa ~/.indent.pro , +to be ignored. +.It Fl pcs , npcs +If true +.Pq Fl pcs +all procedure calls will have a space inserted between +the name and the `('. +Default: +.Fl npcs . +.It Fl psl , npsl +If true +.Pq Fl psl +the names of procedures being defined are placed in +column 1 \- their types, if any, will be left on the previous lines. +Default: +.Fl psl . +.It Fl \&sc , nsc +Enables (disables) the placement of asterisks (`*'s) at the left edge of all +comments. +Default: +.Fl sc . +.It Fl sob , nsob +If +.Fl sob +is specified, indent will swallow optional blank lines. +You can use this to get rid of blank lines after declarations. +Default: +.Fl nsob . +.It Fl \&st +Causes +.Nm +to take its input from stdin, and put its output to stdout. +.It Fl T Ns Ar typename +Adds +.Ar typename +to the list of type keywords. +Names accumulate: +.Fl T +can be specified more than once. +You need to specify all the typenames that +appear in your program that are defined by +.Ic typedef +\- nothing will be +harmed if you miss a few, but the program won't be formatted as nicely as +it should. +This sounds like a painful thing to have to do, but it's really +a symptom of a problem in C: +.Ic typedef +causes a syntactic change in the +language and +.Nm +can't find all +instances of +.Ic typedef . +.It Fl troff +Causes +.Nm +to format the program for processing by +.Xr troff 1 . +It will produce a fancy +listing in much the same spirit as +.Xr vgrind 1 . +If the output file is not specified, the default is standard output, +rather than formatting in place. +.It Fl v , \&nv +.Fl v +turns on `verbose' mode; +.Fl \&nv +turns it off. +When in verbose mode, +.Nm +reports when it splits one line of input into two or more lines of output, +and gives some size statistics at completion. +Default: +.Fl \&nv . +.El +.Pp +You may set up your own `profile' of defaults to +.Nm +by creating a file called +.Pa .indent.pro +in your login directory and/or the current directory and including +whatever switches you like. +A `.indent.pro' in the current directory takes +precedence over the one in your login directory. +If +.Nm +is run and a profile file exists, then it is read to set up the program's +defaults. +Switches on the command line, though, always override profile switches. +The switches should be separated by spaces, tabs or newlines. +.Ss Comments +.Sq Em Box +.Em comments . +.Nm +assumes that any comment with a dash or star immediately after the start of +comment (that is, `/*\-' or `/**') is a comment surrounded by a box of stars. +Each line of such a comment is left unchanged, except that its indentation +may be adjusted to account for the change in indentation of the first line +of the comment. +.Pp +.Em Straight text . +All other comments are treated as straight text. +.Nm +fits as many words (separated by blanks, tabs, or newlines) on a +line as possible. +Blank lines break paragraphs. +.Ss Comment indentation +If a comment is on a line with code it is started in the `comment column', +which is set by the +.Fl c Ns Ns Ar n +command line parameter. +Otherwise, the comment is started at +.Ar n +indentation levels less than where code is currently being placed, where +.Ar n +is specified by the +.Fl d Ns Ns Ar n +command line parameter. +If the code on a line extends past the comment +column, the comment starts further to the right, and the right margin may be +automatically extended in extreme cases. +.Ss Preprocessor lines +In general, +.Nm +leaves preprocessor lines alone. +The only reformatting that it will do is to straighten up trailing comments. +It leaves embedded comments alone. +Conditional compilation +.Pq Ic #ifdef...#endif +is recognized and +.Nm +attempts to correctly +compensate for the syntactic peculiarities introduced. +.Ss C syntax +.Nm +understands a substantial amount about the syntax of C, but it +has a `forgiving' parser. +It attempts to cope with the usual sorts of incomplete and misformed syntax. +In particular, the use of macros like: +.Pp +.Dl #define forever for(;;) +.Pp +is handled properly. +.Sh ENVIRONMENT +.Nm +uses the +.Ev HOME +environment variable. +.Sh FILES +.Bl -tag -width "./.indent.pro" -compact +.It Pa ./.indent.pro +profile file +.It Pa ~/.indent.pro +profile file +.El +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.2 . +.Sh BUGS +.Nm +has even more switches than +.Xr ls 1 . +.Pp +A common mistake that often causes grief is typing: +.Pp +.Dl indent *.c +.Pp +to the shell in an attempt to indent all the +.Tn C +programs in a directory. +This is probably a bug, not a feature. diff --git a/usr.bin/indent/indent.c b/usr.bin/indent/indent.c new file mode 100644 index 000000000..8001931a6 --- /dev/null +++ b/usr.bin/indent/indent.c @@ -0,0 +1,1281 @@ +/* $NetBSD: indent.c,v 1.18 2009/04/12 11:09:49 lukem Exp $ */ + +/* + * 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. 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. + */ + +/* + * Copyright (c) 1976 Board of Trustees of the University of Illinois. + * Copyright (c) 1985 Sun Microsystems, Inc. + * 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. + */ + +#include +#ifndef lint +__COPYRIGHT("@(#) 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."); +#endif /* not lint */ + +#ifndef lint +#if 0 +static char sccsid[] = "@(#)indent.c 5.17 (Berkeley) 6/7/93"; +#else +__RCSID("$NetBSD: indent.c,v 1.18 2009/04/12 11:09:49 lukem Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define EXTERN +#include "indent_globs.h" +#undef EXTERN +#include "indent_codes.h" + +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 */ +char bakfile[MAXPATHLEN] = ""; + +int main(int, char **); + +int +main(int argc, char **argv) +{ + + extern int found_err; /* flag set in diag() on error */ + int dec_ind; /* current indentation for declarations */ + int di_stack[20]; /* a stack of structure indentation levels */ + int flushed_nl; /* used when buffering up comments to remember + * that a newline was passed over */ + int force_nl; /* when true, code must be broken */ + int hd_type; /* 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 expressin 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 type_code; /* the type of token, returned by lexi */ + + int last_else = 0; /* true iff last keyword was an else */ + + + /*-----------------------------------------------*\ + | INITIALIZATION | + \*-----------------------------------------------*/ + + if (!setlocale(LC_ALL, "")) + fprintf(stderr, "indent: can't set locale.\n"); + + hd_type = 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); + labbuf = (char *) malloc(bufsize); + codebuf = (char *) malloc(bufsize); + tokenbuf = (char *) malloc(bufsize); + 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 */ + 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); + 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 = 0; + bp_save = 0; + be_save = 0; + + output = 0; + + + + /*--------------------------------------------------*\ + | COMMAND LINE SCAN | + \*--------------------------------------------------*/ + +#ifdef undef + max_col = 78; /* -l78 */ + lineup_to_parens = 1; /* -lp */ + 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.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_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; + set_defaults(); + if (i >= argc) + set_profile(); + + 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 == 0) { /* we must have the input file */ + in_name = argv[i]; /* remember name of + * input file */ + input = fopen(in_name, "r"); + if (input == 0) /* check for open error */ + err(1, "%s", in_name); + continue; + } else + if (output == 0) { /* 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 */ + fprintf(stderr, "indent: input and output files must be different\n"); + exit(1); + } + output = fopen(out_name, "w"); + if (output == 0) /* check for create + * error */ + err(1, "%s", out_name); + continue; + } + fprintf(stderr, "indent: unknown parameter: %s\n", argv[i]); + exit(1); + } else + set_option(argv[i]); + } /* end of for */ + if (input == 0) { + input = stdin; + } + if (output == 0) { + if (troff || input == stdin) + output = stdout; + else { + out_name = in_name; + bakcopy(); + } + } + if (ps.com_ind <= 1) + ps.com_ind = 2; /* dont put normal comments before column 2 */ + if (troff) { + if (bodyf.font[0] == 0) + parsefont(&bodyf, "R"); + if (scomf.font[0] == 0) + parsefont(&scomf, "I"); + if (blkcomf.font[0] == 0) + blkcomf = scomf, blkcomf.size += 2; + if (boxcomf.font[0] == 0) + boxcomf = blkcomf; + if (stringf.font[0] == 0) + parsefont(&stringf, "L"); + if (keywordf.font[0] == 0) + parsefont(&keywordf, "B"); + writefdef(&bodyf, 'B'); + writefdef(&scomf, 'C'); + writefdef(&blkcomf, 'L'); + writefdef(&boxcomf, 'X'); + writefdef(&stringf, 'S'); + writefdef(&keywordf, 'K'); + } + if (block_comment_max_col <= 0) + block_comment_max_col = max_col; + 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; + 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 = ((col - 1) & ~7) + 9; + else + break; + p++; + } + if (col > ps.ind_size) + ps.ind_level = ps.i_l_follow = col / ps.ind_size; + } + if (troff) { + const char *p = in_name, *beg = in_name; + + while (*p) + if (*p++ == '/') + beg = p; + fprintf(output, ".Fn \"%s\"\n", beg); + } + /* + * START OF MAIN LOOP + */ + + while (1) { /* this is the main loop. it will go until we + * reach eof */ + int is_procname; + + type_code = lexi(); /* lexi reads one token. The actual + * characters read are stored in + * "token". lexi returns a code + * indicating the type of token */ + is_procname = ps.procname[0]; + + /* + * The following code moves everything 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. + */ + + flushed_nl = false; + while (ps.search_brace) { /* if we scanned an if(), + * while(), etc., we might + * need to copy stuff into a + * buffer we must loop, + * copying stuff into + * save_com, until we find the + * start of the stmt which + * follows the if, or whatever */ + switch (type_code) { + case newline: + ++line_no; + flushed_nl = true; + case form_feed: + break; /* form feeds and newlines found here + * will be ignored */ + + case lbrace: /* this is a brace that starts the + * compound stmt */ + if (sc_end == 0) { /* ignore buffering if a + * comment wasnt stored + * up */ + ps.search_brace = false; + goto check_type; + } + if (btype_2) { + save_com[0] = '{'; /* we either want to put + * the brace right after + * the if */ + goto sw_buffer; /* go to common code to + * get out of this loop */ + } + case comment: /* we have a comment, so we must copy + * it into the buffer */ + if (!flushed_nl || sc_end != 0) { + if (sc_end == 0) { /* if this is the first + * comment, we must set + * up the buffer */ + save_com[0] = save_com[1] = ' '; + sc_end = &(save_com[2]); + } else { + *sc_end++ = '\n'; /* add newline between + * comments */ + *sc_end++ = ' '; + --line_no; + } + *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 */ + diag(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; + } + default: /* it is the start of a normal + * statment */ + if (flushed_nl) /* if we flushed a newline, + * make sure it is put back */ + force_nl = true; + if ((type_code == sp_paren && *token == 'i' + && last_else && ps.else_if) || + (type_code == sp_nparen && *token == 'e' + && e_code != s_code && e_code[-1] == '}')) + force_nl = false; + + if (sc_end == 0) { /* ignore buffering if + * comment wasnt saved + * up */ + ps.search_brace = false; + goto check_type; + } + 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 + * nl is read from the + * buffer */ + *sc_end++ = '\n'; + *sc_end++ = ' '; + if (verbose && !flushed_nl) /* print error msg if + * the line was not + * already broken */ + diag(0, "Line broken"); + flushed_nl = false; + } + for (t_ptr = token; *t_ptr; ++t_ptr) + *sc_end++ = *t_ptr; /* copy token into temp + * buffer */ + ps.procname[0] = 0; + + 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 = 0; + break; + } /* end of switch */ + if (type_code != 0) /* we must make this check, + * just in case there was an + * unexpected EOF */ + type_code = lexi(); /* read another token */ + /* if (ps.search_brace) ps.procname[0] = 0; */ + if ((is_procname = ps.procname[0]) && flushed_nl + && !procnames_start_line && ps.in_decl + && type_code == ident) + flushed_nl = 0; + } /* 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 */ + diag(1, "Stuff missing from end of file."); + + if (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)) { + /* we should force a broken line here */ + if (verbose && !flushed_nl) + diag(0, "Line broken"); + flushed_nl = false; + 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 */ + *e_code++ = ' '; + for (t_ptr = s_com; *t_ptr; ++t_ptr) { + CHECK_SIZE_CODE; + *e_code++ = *t_ptr; + } + *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; + 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) { + dump_line(); + ps.want_blank = false; + } + ++line_no; /* keep track of input line number */ + break; + + case lparen: /* got a '(' or '[' */ + ++ps.p_l_follow; /* count parens to make Healy + * happy */ + if (ps.want_blank && *token != '[' && + (ps.last_token != ident || proc_calls_space + || (ps.its_a_keyword && (!ps.sizeof_keyword || Bill_Shannon)))) + *e_code++ = ' '; + if (ps.in_decl && !ps.block_init) { + if (troff && !ps.dumped_decl_indent && !is_procname && ps.last_token == decl) { + ps.dumped_decl_indent = 1; + sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); + e_code += strlen(e_code); + } else { + while ((e_code - s_code) < dec_ind) { + CHECK_SIZE_CODE; + *e_code++ = ' '; + } + *e_code++ = token[0]; + } + } else + *e_code++ = token[0]; + ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code; + 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; + ps.want_blank = false; + 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 */ + } + if (ps.sizeof_keyword) + ps.sizeof_mask |= 1 << ps.p_l_follow; + break; + + case rparen: /* got a ')' or ']' */ + rparen_count--; + if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask) { + ps.last_u_d = true; + ps.cast_mask &= (1 << ps.p_l_follow) - 1; + } + ps.sizeof_mask &= (1 << ps.p_l_follow) - 1; + if (--ps.p_l_follow < 0) { + ps.p_l_follow = 0; + diag(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]; + ps.want_blank = true; + + 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 */ + break; + + case unary_op: /* this could be any unary operation */ + if (ps.want_blank) + *e_code++ = ' '; + + if (troff && !ps.dumped_decl_indent && ps.in_decl && !is_procname) { + sprintf(e_code, "\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token); + ps.dumped_decl_indent = 1; + e_code += strlen(e_code); + } else { + const char *res = token; + + if (ps.in_decl && !ps.block_init) { /* if this is a unary op + * in a declaration, we + * should indent this + * token */ + for (i = 0; token[i]; ++i); /* find length of token */ + while ((e_code - s_code) < (dec_ind - i)) { + CHECK_SIZE_CODE; + *e_code++ = ' '; /* pad it */ + } + } + if (troff && token[0] == '-' && token[1] == '>') + res = "\\(->"; + for (t_ptr = res; *t_ptr; ++t_ptr) { + CHECK_SIZE_CODE; + *e_code++ = *t_ptr; + } + } + ps.want_blank = false; + break; + + case binary_op:/* any binary operation */ + if (ps.want_blank) + *e_code++ = ' '; + { + const char *res = token; + + if (troff) + switch (token[0]) { + case '<': + if (token[1] == '=') + res = "\\(<="; + break; + case '>': + if (token[1] == '=') + res = "\\(>="; + break; + case '!': + if (token[1] == '=') + res = "\\(!="; + break; + case '|': + if (token[1] == '|') + res = "\\(br\\(br"; + else + if (token[1] == 0) + res = "\\(br"; + break; + } + for (t_ptr = res; *t_ptr; ++t_ptr) { + CHECK_SIZE_CODE; + *e_code++ = *t_ptr; /* move the operator */ + } + } + 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 */ + for (t_ptr = s_code; *t_ptr; ++t_ptr) + *e_lab++ = *t_ptr; /* turn everything so + * far into a label */ + e_code = s_code; + *e_lab++ = ':'; + *e_lab++ = ' '; + *e_lab = '\0'; + + 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 ';' */ + ps.in_or_st = false; /* we are not in an + * initialization or structure + * declaration */ + scase = false; /* these will only need resetting in a + * error */ + squest = 0; + if (ps.last_token == rparen && rparen_count == 0) + ps.in_parameter_declaration = 0; + ps.cast_mask = 0; + ps.sizeof_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) + while ((e_code - s_code) < (dec_ind - 1)) { + CHECK_SIZE_CODE; + *e_code++ = ' '; + } + + 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 + */ + diag(1, "Unbalanced parens"); + ps.p_l_follow = 0; + if (sp_sw) { /* this is a check for a 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 a + * 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) { + dump_line(); + ps.want_blank = false; + } else + if (ps.in_parameter_declaration && !ps.in_or_st) { + ps.i_l_follow = 0; + dump_line(); + ps.want_blank = false; + } + } + if (ps.in_parameter_declaration) + prefix_blankline_requested = 0; + + if (ps.p_l_follow > 0) { /* check for preceding + * unbalanced parens */ + diag(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; + /* ? dec_ind = 0; */ + } else { + ps.decl_on_line = false; /* we cant be in the + * middle of a + * declaration, so dont + * do special + * indentation of + * comments */ + if (blanklines_after_declarations_at_proctop + && ps.in_parameter_declaration) + postfix_blankline_requested = 1; + ps.in_parameter_declaration = 0; + } + 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. */ + diag(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) + diag(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.il[ps.tos] >= ps.ind_level; + if (ps.tos <= 1 && 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) + diag(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) + diag(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 decl: /* we have a declaration type (int, register, + * etc.) */ + parse(decl); /* let parser worry about indentation */ + if (ps.last_token == rparen && ps.tos <= 1) { + ps.in_parameter_declaration = 1; + if (s_code != e_code) { + dump_line(); + ps.want_blank = 0; + } + } + if (ps.in_parameter_declaration && ps.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 = true; + 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 */ + + /* + * dec_ind = e_code - s_code + (ps.decl_indent>i ? ps.decl_indent + * : i); + */ + dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i; + goto copy_id; + + case ident: /* got an identifier or constant */ + if (ps.in_decl) { /* if we are in a declaration, + * we must indent identifier */ + if (ps.want_blank) + *e_code++ = ' '; + ps.want_blank = false; + if (is_procname == 0 || !procnames_start_line) { + if (!ps.block_init) { + if (troff && !ps.dumped_decl_indent) { + sprintf(e_code, "\n.De %dp+\200p\n", dec_ind * 7); + ps.dumped_decl_indent = 1; + e_code += strlen(e_code); + } else + while ((e_code - s_code) < dec_ind) { + CHECK_SIZE_CODE; + *e_code++ = ' '; + } + } + } else { + if (dec_ind && s_code != e_code) + dump_line(); + dec_ind = 0; + 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: + if (ps.want_blank) + *e_code++ = ' '; + if (troff && ps.its_a_keyword) { + e_code = chfont(&bodyf, &keywordf, e_code); + for (t_ptr = token; *t_ptr; ++t_ptr) { + CHECK_SIZE_CODE; + *e_code++ = keywordf.allcaps + ? toupper((unsigned char)*t_ptr) + : *t_ptr; + } + e_code = chfont(&keywordf, &bodyf, e_code); + } else + for (t_ptr = token; *t_ptr; ++t_ptr) { + CHECK_SIZE_CODE; + *e_code++ = *t_ptr; + } + ps.want_blank = true; + 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 && is_procname == 0 && !ps.block_init) + while ((e_code - s_code) < (dec_ind - 1)) { + CHECK_SIZE_CODE; + *e_code++ = ' '; + } + + *e_code++ = ','; + if (ps.p_l_follow == 0) { + if (ps.block_init_level <= 0) + ps.block_init = 0; + if (break_comma && (!ps.leave_comma || compute_code_target() + (e_code - s_code) > max_col - 8)) + force_nl = true; + } + break; + + case preesc: /* got the character '#' */ + if ((s_com != e_com) || + (s_lab != e_lab) || + (s_code != e_code)) + dump_line(); + *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) { + CHECK_SIZE_LAB; + *e_lab = *buf_ptr++; + if (buf_ptr >= buf_end) + fill_buffer(); + switch (*e_lab++) { + case BACKSLASH: + if (troff) + *e_lab++ = 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 == 0) { /* comment on + * preprocessor line */ + if (sc_end == 0) /* if this is the first + * comment, we must set + * up the buffer */ + sc_end = &(save_com[0]); + else { + *sc_end++ = '\n'; /* add newline between + * comments */ + *sc_end++ = ' '; + --line_no; + } + memmove(sc_end, s_lab + com_start, com_end - com_start); + sc_end += com_end - com_start; + if (sc_end >= &save_com[sc_size]) + abort(); + 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 = 0; + } + *e_lab = '\0'; /* null terminate line */ + ps.pcase = false; + } + + if (strncmp(s_lab, "#if", 3) == 0) { + if (blanklines_around_conditional_compilation) { + int c; + prefix_blankline_requested++; + while ((c = getc(input)) == '\n'); + ungetc(c, input); + } + if (ifdef_level < (int)(sizeof state_stack / sizeof state_stack[0])) { + match_state[ifdef_level].tos = -1; + state_stack[ifdef_level++] = ps; + } else + diag(1, "#if stack overflow"); + } else + if (strncmp(s_lab, "#else", 5) == 0) { + if (ifdef_level <= 0) + diag(1, "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) + diag(1, "Unmatched #endif"); + else { + ifdef_level--; + +#ifdef undef + /* + * This match needs to be more intelligent before the + * message is useful + */ + if (match_state[ifdef_level].tos >= 0 + && memcmp(&ps, &match_state[ifdef_level], sizeof ps)) + diag(0, "Syntactically inconsistant #ifdef alternatives."); +#endif + } + if (blanklines_around_conditional_compilation) { + postfix_blankline_requested++; + n_real_blanklines = 0; + } + } + break; /* subsequent processing of the newline + * character will cause the line to be printed */ + + case comment: /* we have gotten a start comment */ + /* this is a biggie */ + if (flushed_nl) { /* we should force a broken + * line here */ + flushed_nl = false; + dump_line(); + ps.want_blank = false; /* dont insert blank at + * line start */ + force_nl = false; + } + 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 + */ +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.BAK", p); + + /* 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 == 0) + err(1, "%s", bakfile); + /* now the original input file will be the output */ + output = fopen(in_name, "w"); + if (output == 0) { + unlink(bakfile); + err(1, "%s", in_name); + } +} diff --git a/usr.bin/indent/indent_codes.h b/usr.bin/indent/indent_codes.h new file mode 100644 index 000000000..d65c3210d --- /dev/null +++ b/usr.bin/indent/indent_codes.h @@ -0,0 +1,101 @@ +/* $NetBSD: indent_codes.h,v 1.5 2003/08/07 11:14:08 agc Exp $ */ + +/* + * 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. 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. + * + * from: @(#)indent_codes.h 8.1 (Berkeley) 6/6/93 + */ + +/* + * Copyright (c) 1985 Sun Microsystems, Inc. + * Copyright (c) 1976 Board of Trustees of the University of Illinois. + * 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. + * + * from: @(#)indent_codes.h 8.1 (Berkeley) 6/6/93 + */ + +#define newline 1 +#define lparen 2 +#define rparen 3 +#define unary_op 4 +#define binary_op 5 +#define postop 6 +#define question 7 +#define casestmt 8 +#define colon 9 +#define semicolon 10 +#define lbrace 11 +#define rbrace 12 +#define ident 13 +#define comma 14 +#define comment 15 +#define swstmt 16 +#define preesc 17 +#define form_feed 18 +#define decl 19 +#define sp_paren 20 +#define sp_nparen 21 +#define ifstmt 22 +#define whilestmt 23 +#define forstmt 24 +#define stmt 25 +#define stmtl 26 +#define elselit 27 +#define dolit 28 +#define dohead 29 +#define ifhead 30 +#define elsehead 31 +#define period 32 diff --git a/usr.bin/indent/indent_globs.h b/usr.bin/indent/indent_globs.h new file mode 100644 index 000000000..f7a8426c6 --- /dev/null +++ b/usr.bin/indent/indent_globs.h @@ -0,0 +1,363 @@ +/* $NetBSD: indent_globs.h,v 1.9 2009/04/12 11:09:49 lukem Exp $ */ + +/* + * 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. 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. + * + * from: @(#)indent_globs.h 8.1 (Berkeley) 6/6/93 + */ + +/* + * Copyright (c) 1985 Sun Microsystems, Inc. + * Copyright (c) 1976 Board of Trustees of the University of Illinois. + * 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. + * + * from: @(#)indent_globs.h 8.1 (Berkeley) 6/6/93 + */ + +#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 tabsize 8 /* the size of a tab */ +#define tabmask 0177770 /* mask used when figuring length of lines + * with tabs */ + + +#define false 0 +#define true 1 + + +#ifndef EXTERN +#define EXTERN extern +#endif + + +EXTERN FILE *input; /* the fid for the input file */ +EXTERN FILE *output; /* the output file */ + +#define CHECK_SIZE_CODE \ + if (e_code >= l_code) { \ + int nsize = l_code-s_code+400; \ + codebuf = (char *) realloc(codebuf, nsize); \ + e_code = codebuf + (e_code-s_code) + 1; \ + l_code = codebuf + nsize - 5; \ + s_code = codebuf + 1; \ + } +#define CHECK_SIZE_COM \ + if (e_com >= l_com) { \ + int nsize = l_com-s_com+400; \ + combuf = (char *) realloc(combuf, nsize); \ + e_com = combuf + (e_com-s_com) + 1; \ + l_com = combuf + nsize - 5; \ + s_com = combuf + 1; \ + } +#define CHECK_SIZE_LAB \ + if (e_lab >= l_lab) { \ + int nsize = l_lab-s_lab+400; \ + labbuf = (char *) realloc(labbuf, nsize); \ + e_lab = labbuf + (e_lab-s_lab) + 1; \ + l_lab = labbuf + nsize - 5; \ + s_lab = labbuf + 1; \ + } +#define CHECK_SIZE_TOKEN \ + if (e_token >= l_token) { \ + int nsize = l_token-s_token+400; \ + tokenbuf = (char *) realloc(tokenbuf, nsize); \ + e_token = tokenbuf + (e_token-s_token) + 1; \ + l_token = tokenbuf + nsize - 5; \ + s_token = tokenbuf + 1; \ + } + +EXTERN char *labbuf; /* buffer for label */ +EXTERN char *s_lab; /* start ... */ +EXTERN char *e_lab; /* .. and end of stored label */ +EXTERN char *l_lab; /* limit of label buffer */ + +EXTERN char *codebuf; /* buffer for code section */ +EXTERN char *s_code; /* start ... */ +EXTERN char *e_code; /* .. and end of stored code */ +EXTERN char *l_code; /* limit of code section */ + +EXTERN char *combuf; /* buffer for comments */ +EXTERN char *s_com; /* start ... */ +EXTERN char *e_com; /* ... and end of stored comments */ +EXTERN char *l_com; /* limit of comment buffer */ + +#define token s_token +EXTERN char *tokenbuf; /* the last token scanned */ +EXTERN char *s_token; +EXTERN char *e_token; +EXTERN char *l_token; + +EXTERN char *in_buffer; /* input buffer */ +EXTERN char *in_buffer_limit; /* the end of the input buffer */ +EXTERN char *buf_ptr; /* ptr to next character to be taken from + * in_buffer */ +EXTERN char *buf_end; /* ptr to first after last char in in_buffer */ + +EXTERN char save_com[sc_size]; /* input text is saved here when looking for + * the brace after an if, while, etc */ +EXTERN char *sc_end; /* pointer into save_com buffer */ + +EXTERN char *bp_save; /* saved value of buf_ptr when taking input + * from save_com */ +EXTERN char *be_save; /* similarly saved value of buf_end */ + + +EXTERN int pointer_as_binop; +EXTERN int blanklines_after_declarations; +EXTERN int blanklines_before_blockcomments; +EXTERN int blanklines_after_procs; +EXTERN int blanklines_around_conditional_compilation; +EXTERN int swallow_optional_blanklines; +EXTERN int n_real_blanklines; +EXTERN int prefix_blankline_requested; +EXTERN int postfix_blankline_requested; +EXTERN int break_comma; /* when true and not in parens, break after a + * comma */ +EXTERN int btype_2; /* when true, brace should be on same line as + * if, while, etc */ +EXTERN float case_ind; /* indentation level to be used for a "case + * n:" */ +EXTERN int code_lines; /* count of lines with code */ +EXTERN int had_eof; /* set to true when input is exhausted */ +EXTERN int line_no; /* the current line number. */ +EXTERN int max_col; /* the maximum allowable line length */ +EXTERN int verbose; /* when true, non-essential error messages are + * printed */ +EXTERN int cuddle_else; /* true if else should cuddle up to '}' */ +EXTERN int star_comment_cont; /* true iff comment continuation lines should + * have stars at the beginning of each line. */ +EXTERN int comment_delimiter_on_blankline; +EXTERN int troff; /* true iff were generating troff input */ +EXTERN 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) */ +EXTERN int proc_calls_space; /* If true, procedure calls look like: + * foo(bar) rather than foo (bar) */ +EXTERN int format_col1_comments; /* If comments which start in column 1 are to + * be magically reformatted (just like + * comments that begin in later columns) */ +EXTERN int inhibit_formatting; /* true if INDENT OFF is in effect */ +EXTERN int suppress_blanklines; /* set iff following blanklines should be + * suppressed */ +EXTERN int continuation_indent; /* set to the indentation between the edge of + * code and continuation lines */ +EXTERN int lineup_to_parens; /* if true, continued code within parens will + * be lined up to the open paren */ +EXTERN int Bill_Shannon; /* true iff a blank should always be inserted + * after sizeof */ +EXTERN 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 */ +EXTERN int block_comment_max_col; +EXTERN 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 */ + +/* -troff font state information */ + +struct fstate { + char font[4]; + char size; + int allcaps:1; +}; + +EXTERN struct fstate + keywordf, /* keyword font */ + stringf, /* string font */ + boxcomf, /* Box comment font */ + blkcomf, /* Block comment font */ + scomf, /* Same line comment font */ + bodyf; /* major body font */ + +#define STACK_SIZE 150 + +EXTERN struct parser_state { + int last_token; + struct fstate cfont; /* Current font */ + int p_stack[STACK_SIZE]; /* this is the parsers stack */ + int il[STACK_SIZE]; /* this stack stores indentation levels */ + float cstk[STACK_SIZE];/* 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 comment / */ + int comment_delta, n_comment_delta; + int cast_mask; /* indicates which close parens close off + * casts */ + int sizeof_mask; /* indicates which close parens close off + * sizeof''s */ + 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 + * coment 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 stmts */ + 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 its_a_keyword; + int sizeof_keyword; + 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; + +EXTERN int ifdef_level; +EXTERN int rparen_count; +EXTERN struct parser_state state_stack[5]; +EXTERN struct parser_state match_state[5]; + +int compute_code_target(void); +int compute_label_target(void); +int count_spaces(int, char *); +void diag(int, const char *,...) __attribute__((__format__(__printf__, 2, 3))); +void dump_line(void); +int eqin(const char *, const char *); +void fill_buffer(void); +int pad_output(int, int); +void scan_profile(FILE *); +void set_defaults(void); +void set_option(char *); +void addkey(char *, int); +void set_profile(void); +char *chfont(struct fstate *, struct fstate *, char *); +void parsefont(struct fstate *, const char *); +void writefdef(struct fstate *, int); +int lexi(void); +void reduce(void); +void parse(int); +void pr_comment(void); +void bakcopy(void); diff --git a/usr.bin/indent/io.c b/usr.bin/indent/io.c new file mode 100644 index 000000000..849fb0a81 --- /dev/null +++ b/usr.bin/indent/io.c @@ -0,0 +1,685 @@ +/* $NetBSD: io.c,v 1.14 2009/04/12 11:09:49 lukem Exp $ */ + +/* + * 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. 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. + */ + +/* + * Copyright (c) 1976 Board of Trustees of the University of Illinois. + * Copyright (c) 1985 Sun Microsystems, Inc. + * 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. + */ + +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)io.c 8.1 (Berkeley) 6/6/93"; +#else +__RCSID("$NetBSD: io.c,v 1.14 2009/04/12 11:09:49 lukem Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include +#include "indent_globs.h" + +int comment_open; +static int paren_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; + static int not_first_line; + + target_col = 0; + if (ps.procname[0]) { + if (troff) { + if (comment_open) { + comment_open = 0; + fprintf(output, ".*/\n"); + } + fprintf(output, ".Pr \"%s\"\n", ps.procname); + } + 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 (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--; + 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) { + if (troff) { + int all_here = 0; + char *p; + + if (e_com[-1] == '/' && e_com[-2] == '*') + e_com -= 2, all_here++; + while (e_com > s_com && e_com[-1] == ' ') + e_com--; + *e_com = 0; + p = s_com; + while (*p == ' ') + p++; + if (p[0] == '/' && p[1] == '*') + p += 2, all_here++; + else + if (p[0] == '*') + p += p[1] == '/' ? 2 : 1; + while (*p == ' ') + p++; + if (*p == 0) + goto inhibit_newline; + if (comment_open < 2 && ps.box_com) { + comment_open = 0; + fprintf(output, ".*/\n"); + } + if (comment_open == 0) { + if ('a' <= *p && *p <= 'z') + *p = *p + 'A' - 'a'; + if (e_com - p < 50 && all_here == 2) { + char *follow = p; + fprintf(output, "\n.nr C! \\w\1"); + while (follow < e_com) { + switch (*follow) { + case '\n': + putc(' ', output); + case 1: + break; + case '\\': + putc('\\', output); + default: + putc(*follow, output); + } + follow++; + } + putc(1, output); + } + fprintf(output, "\n./* %dp %d %dp\n", + ps.com_col * 7, + (s_code != e_code || s_lab != e_lab) - ps.box_com, + target_col * 7); + } + comment_open = 1 + ps.box_com; + while (*p) { + if (*p == BACKSLASH) + putc(BACKSLASH, output); + putc(*p++, output); + } + } else { /* print comment, if any */ + int target = ps.com_col; + char *com_st = s_com; + + target += ps.comment_delta; + while (*com_st == '\t') + com_st++, target += 8; /* ? */ + while (target <= 0) + if (*com_st == ' ') + target++, com_st++; + else + if (*com_st == '\t') + target = ((target - 1) & ~7) + 9, com_st++; + else + target = 1; + if (cur_col > target) { /* if comment cant 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--; + cur_col = pad_output(cur_col, target); + if (!ps.box_com) { + if (star_comment_cont + && (com_st[1] != '*' + || e_com <= com_st + 1)) { + if (com_st[1] == ' ' + && com_st[0] == ' ' + && e_com > com_st + 1) + com_st[1] = '*'; + else + fwrite(" * ", + com_st[0] == '\t' + ? 2 + : com_st[0]=='*' + ? 1 + : 3, 1, output); + } + } + fwrite(com_st, + e_com - com_st, 1, output); + ps.comment_delta = ps.n_comment_delta; + cur_col = count_spaces(cur_col, com_st); + ++ps.com_lines; /* count lines with + * comments */ + } + } + if (ps.use_ff) + putc('\014', output); + else + putc('\n', output); + inhibit_newline: + ++ps.out_lines; + if (ps.just_saw_decl == 1 && 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) = '\0'; + ps.ind_level = ps.i_l_follow; + ps.paren_level = ps.p_l_follow; + 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; + + if (ps.paren_level) { + if (!lineup_to_parens) + target_col += continuation_indent * ps.paren_level; + 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) { + t -= w + 1; + if (t > target_col) + target_col = t; + } else + target_col = t; + } + } else + if (ps.ind_stmt) + target_col += continuation_indent; + return target_col; +} + +int +compute_label_target(void) +{ + return + ps.pcase ? (int) (case_ind * ps.ind_size) + 1 + : *s_lab == '#' ? 1 + : ps.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; + char *n; + + if (bp_save != 0) { /* there is a partly filled input buffer left */ + buf_ptr = bp_save; /* dont read anything, just switch + * buffers */ + buf_end = be_save; + bp_save = be_save = 0; + 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; + n = (char *) realloc(in_buffer, size); + if (n == 0) + errx(1, "input line too long"); + in_buffer = n; + p = in_buffer + offset; + in_buffer_limit = in_buffer + size - 2; + } + if ((i = getc(f)) == EOF) { + *p++ = ' '; + *p++ = '\n'; + had_eof = true; + break; + } + *p++ = i; + if (i == '\n') + break; + } + buf_ptr = in_buffer; + buf_end = p; + if (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 + * target integer 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 + * + */ +int +pad_output(int current, int target) +{ + int curr; /* internal column pointer */ + int tcur; + + if (troff) + fprintf(output, "\\h'|%dp'", (target - 1) * 7); + else { + if (current >= target) + return (current); /* line is already long enough */ + curr = current; + while ((tcur = ((curr - 1) & tabmask) + 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(int current, char *buffer) +/* + * 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 */ + int cur; /* current character counter */ + + cur = current; + + for (buf = buffer; *buf != '\0'; ++buf) { + switch (*buf) { + + case '\n': + case 014: /* form feed */ + cur = 1; + break; + + case '\t': + cur = ((cur - 1) & tabmask) + tabsize + 1; + break; + + case 010: /* backspace */ + --cur; + break; + + default: + ++cur; + break; + } /* end of switch */ + } /* end of for loop */ + return (cur); +} + + +int found_err; + +void +diag(int level, const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + + if (level) + found_err = 1; + if (output == stdout) { + fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no); + vfprintf(stdout, msg, ap); + fprintf(stdout, " */\n"); + } else { + fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no); + vfprintf(stdout, msg, ap); + fprintf(stderr, "\n"); + } + va_end(ap); +} + +void +writefdef(struct fstate *f, int nm) +{ + fprintf(output, ".ds f%c %s\n.nr s%c %d\n", + nm, f->font, nm, f->size); +} + +char * +chfont(struct fstate *of, struct fstate *nf, char *s) +{ + if (of->font[0] != nf->font[0] + || of->font[1] != nf->font[1]) { + *s++ = '\\'; + *s++ = 'f'; + if (nf->font[1]) { + *s++ = '('; + *s++ = nf->font[0]; + *s++ = nf->font[1]; + } else + *s++ = nf->font[0]; + } + if (nf->size != of->size) { + *s++ = '\\'; + *s++ = 's'; + if (nf->size < of->size) { + *s++ = '-'; + *s++ = '0' + of->size - nf->size; + } else { + *s++ = '+'; + *s++ = '0' + nf->size - of->size; + } + } + return s; +} + + +void +parsefont(struct fstate *f, const char *s0) +{ + const char *s = s0; + int sizedelta = 0; + memset(f, 0, sizeof *f); + while (*s) { + if (isdigit((unsigned char)*s)) + f->size = f->size * 10 + *s - '0'; + else + if (isupper((unsigned char)*s)) { + if (f->font[0]) + f->font[1] = *s; + else + f->font[0] = *s; + } else + if (*s == 'c') + f->allcaps = 1; + else + if (*s == '+') + sizedelta++; + else + if (*s == '-') + sizedelta--; + else { + fprintf(stderr, "indent: bad font specification: %s\n", s0); + exit(1); + } + s++; + } + if (f->font[0] == 0) + f->font[0] = 'R'; + if (bodyf.size == 0) + bodyf.size = 11; + if (f->size == 0) + f->size = bodyf.size + sizedelta; + else + if (sizedelta > 0) + f->size += bodyf.size; + else + f->size = bodyf.size - f->size; +} diff --git a/usr.bin/indent/lexi.c b/usr.bin/indent/lexi.c new file mode 100644 index 000000000..c56eea37c --- /dev/null +++ b/usr.bin/indent/lexi.c @@ -0,0 +1,630 @@ +/* $NetBSD: lexi.c,v 1.13 2009/04/12 11:09:49 lukem Exp $ */ + +/* + * 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. 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. + */ + +/* + * Copyright (c) 1976 Board of Trustees of the University of Illinois. + * Copyright (c) 1985 Sun Microsystems, Inc. + * 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. + */ + +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)lexi.c 8.1 (Berkeley) 6/6/93"; +#else +__RCSID("$NetBSD: lexi.c,v 1.13 2009/04/12 11:09:49 lukem Exp $"); +#endif +#endif /* not lint */ + +/* + * 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 "indent_globs.h" +#include "indent_codes.h" + +#define alphanum 1 +#define opchar 3 + +struct templ { + const char *rwd; + int rwcode; +}; + +struct templ specials[1000] = +{ + {"switch", 1}, + {"case", 2}, + {"break", 0}, + {"struct", 3}, + {"union", 3}, + {"enum", 3}, + {"default", 2}, + {"int", 4}, + {"char", 4}, + {"float", 4}, + {"double", 4}, + {"long", 4}, + {"short", 4}, + {"typdef", 4}, + {"unsigned", 4}, + {"register", 4}, + {"static", 4}, + {"global", 4}, + {"extern", 4}, + {"void", 4}, + {"goto", 0}, + {"return", 0}, + {"if", 5}, + {"while", 5}, + {"for", 5}, + {"else", 6}, + {"do", 6}, + {"sizeof", 7}, + {0, 0} +}; + +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 +}; + + + + +int +lexi(void) +{ + int unary_delim; /* this is set to 1 if the current token + * + * forces a following operator to be unary */ + static int last_code; /* the last token type returned */ + static int l_struct; /* set to 1 if the last token was 'struct' */ + 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; + ps.col_1 = ps.last_nl; /* tell world that this token started in + * column 1 iff the last thing scanned was nl */ + ps.last_nl = false; + + while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */ + ps.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[(int) *buf_ptr] == alphanum || + (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) { + /* + * we have a character or number + */ + const char *j; /* used for searching thru list of + * reserved words */ + 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; + if (*buf_ptr == '0' && + (buf_ptr[1] == 'x' || buf_ptr[1] == 'X')) { + *e_token++ = *buf_ptr++; + *e_token++ = *buf_ptr++; + while (isxdigit((unsigned char)*buf_ptr)) { + CHECK_SIZE_TOKEN; + *e_token++ = *buf_ptr++; + } + } else { + while (1) { + if (*buf_ptr == '.') { + if (seendot) + break; + else + seendot++; + } + CHECK_SIZE_TOKEN; + *e_token++ = *buf_ptr++; + if (!isdigit((unsigned char)*buf_ptr) + && *buf_ptr != '.') { + if ((*buf_ptr != 'E' + && *buf_ptr != 'e') || seenexp) + break; + else { + seenexp++; + seendot++; + CHECK_SIZE_TOKEN; + *e_token++ = *buf_ptr++; + if (*buf_ptr == '+' || *buf_ptr == '-') + *e_token++ = *buf_ptr++; + } + } + } + } + if (*buf_ptr == 'F' || *buf_ptr == 'f') { + /* float constant */ + *e_token++ = *buf_ptr++; + } else { + /* integer constant */ + while (1) { + if (!(seensfx & 1) && + (*buf_ptr == 'U' || + *buf_ptr == 'u')) { + CHECK_SIZE_TOKEN; + *e_token++ = *buf_ptr++; + seensfx |= 1; + continue; + } + if (!(seensfx & 2) && + (*buf_ptr == 'L' || + *buf_ptr == 'l')) { + CHECK_SIZE_TOKEN; + if (buf_ptr[1] == buf_ptr[0]) + *e_token++ = *buf_ptr++; + *e_token++ = *buf_ptr++; + seensfx |= 2; + continue; + } + break; + } + } + } else + while (chartype[(int) *buf_ptr] == alphanum) { /* copy it over */ + CHECK_SIZE_TOKEN; + *e_token++ = *buf_ptr++; + if (buf_ptr >= buf_end) + fill_buffer(); + } + *e_token++ = '\0'; + while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */ + if (++buf_ptr >= buf_end) + fill_buffer(); + } + ps.its_a_keyword = false; + ps.sizeof_keyword = false; + if (l_struct) { /* if last token was 'struct', then this token + * should be treated as a declaration */ + l_struct = false; + last_code = ident; + ps.last_u_d = true; + return (decl); + } + ps.last_u_d = false; /* Operator after indentifier is + * binary */ + last_code = ident; /* Remember that this is the code we + * will return */ + + /* + * This loop will check if the token is a keyword. + */ + for (p = specials; (j = p->rwd) != 0; p++) { + char *pt = s_token; /* point at scanned token */ + if (*j++ != *pt++ || *j++ != *pt++) + continue; /* This test depends on the + * fact that identifiers are + * always at least 1 character + * long (ie. the first two + * bytes of the identifier are + * always meaningful) */ + if (pt[-1] == 0) + break; /* If its a one-character identifier */ + while (*pt++ == *j) + if (*j++ == 0) + goto found_keyword; /* I wish that C had a + * multi-level break... */ + } + if (p->rwd) { /* we have a keyword */ + found_keyword: + ps.its_a_keyword = true; + ps.last_u_d = true; + switch (p->rwcode) { + case 1:/* it is a switch */ + return (swstmt); + case 2:/* a case or default */ + return (casestmt); + + case 3:/* a "struct" */ + if (ps.p_l_follow) + break; /* inside parens: cast */ + l_struct = true; + + /* + * Next time around, we will want to know that we have had a + * 'struct' + */ + case 4:/* one of the declaration keywords */ + if (ps.p_l_follow) { + ps.cast_mask |= 1 << ps.p_l_follow; + break; /* inside parens: cast */ + } + last_code = decl; + return (decl); + + case 5:/* if, while, for */ + return (sp_paren); + + case 6:/* do, else */ + return (sp_nparen); + + case 7: + ps.sizeof_keyword = true; + default: /* all others are treated like any + * other identifier */ + return (ident); + } /* end of switch */ + } /* end of if (found_it) */ + if (*buf_ptr == '(' && ps.tos <= 1 && ps.ind_level == 0) { + char *tp = buf_ptr; + while (tp < buf_end) + if (*tp++ == ')' && (*tp == ';' || *tp == ',')) + goto not_proc; + strncpy(ps.procname, token, sizeof ps.procname - 1); + ps.in_parameter_declaration = 1; + rparen_count = 1; + 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 + */ + if (((*buf_ptr == '*' && buf_ptr[1] != '=') || + isalpha((unsigned char)*buf_ptr) || *buf_ptr == '_') + && !ps.p_l_follow + && !ps.block_init + && (ps.last_token == rparen || ps.last_token == semicolon || + ps.last_token == decl || + ps.last_token == lbrace || ps.last_token == rbrace)) { + ps.its_a_keyword = true; + ps.last_u_d = true; + last_code = decl; + return decl; + } + if (last_code == decl) /* if this is a declared variable, + * then following sign is unary */ + ps.last_u_d = true; /* will make "int a -1" work */ + last_code = ident; + return (ident); /* the ident is not in the list */ + } /* end of procesing for alpanum character */ + /* Scan a non-alphanumeric token */ + *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 = ps.last_u_d; + ps.last_nl = true; /* remember that we just had a newline */ + code = (had_eof ? 0 : newline); + + /* + * if data has been exausted, the newline is a dummy, and we should + * return code to stop + */ + break; + + case '\'': /* start of quoted character */ + case '"': /* start of string */ + qchar = *token; + if (troff) { + e_token[-1] = '`'; + if (qchar == '"') + *e_token++ = '`'; + e_token = chfont(&bodyf, &stringf, e_token); + } + do { /* copy the string */ + while (1) { /* move one character or + * [/] */ + if (*buf_ptr == '\n') { + printf("%d: Unterminated literal\n", line_no); + goto stop_lit; + } + CHECK_SIZE_TOKEN; /* Only have to do this + * once in this loop, + * since CHECK_SIZE + * guarantees that there + * are at least 5 + * entries left */ + *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; + if (troff) { + *++e_token = BACKSLASH; + if (*buf_ptr == BACKSLASH) + *++e_token = BACKSLASH; + } + *++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); + if (troff) { + e_token = chfont(&stringf, &bodyf, e_token - 1); + if (qchar == '"') + *e_token++ = '\''; + } +stop_lit: + code = ident; + break; + + case ('('): + case ('['): + unary_delim = true; + code = lparen; + break; + + case (')'): + case (']'): + code = rparen; + break; + + case '#': + unary_delim = ps.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 (ps.in_or_st) ps.block_init = 1; + */ + /* ? code = ps.block_init ? lparen : lbrace; */ + code = lbrace; + break; + + case ('}'): + unary_delim = true; + /* ? code = ps.block_init ? rparen : rbrace; */ + code = rbrace; + break; + + case 014: /* a form feed */ + unary_delim = ps.last_u_d; + ps.last_nl = true; /* remember this so we can set + * 'ps.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 = (ps.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 (last_code == ident || last_code == rparen) { + code = (ps.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++; + if (!pointer_as_binop) { + unary_delim = false; + code = unary_op; + ps.want_blank = false; + } + } + break; /* buffer overflow will be checked at end of + * switch */ + + case '=': + if (ps.in_or_st) + ps.block_init = 1; +#ifdef undef + if (chartype[*buf_ptr] == 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 = (ps.last_u_d ? unary_op : binary_op); + unary_delim = true; + 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 = ps.last_u_d; + break; + } + while (*(e_token - 1) == *buf_ptr || *buf_ptr == '=') { + /* + * handle ||, &&, etc, and also things as in int *****i + */ + *e_token++ = *buf_ptr; + if (++buf_ptr >= buf_end) + fill_buffer(); + } + code = (ps.last_u_d ? unary_op : binary_op); + unary_delim = true; + + + } /* end of switch */ + if (code != newline) { + l_struct = false; + last_code = code; + } + if (buf_ptr >= buf_end) /* check for input buffer empty */ + fill_buffer(); + ps.last_u_d = unary_delim; + *e_token = '\0'; /* null terminate the token */ + return (code); +} +/* + * Add the given keyword to the keyword table, using val as the keyword type + */ +void +addkey(char *key, int val) +{ + struct templ *p = specials; + while (p->rwd) + if (p->rwd[0] == key[0] && strcmp(p->rwd, key) == 0) + return; + else + p++; + if (p >= specials + sizeof specials / sizeof specials[0]) + return; /* For now, table overflows are silently + * ignored */ + p->rwd = key; + p->rwcode = val; + p[1].rwd = 0; + p[1].rwcode = 0; +} diff --git a/usr.bin/indent/minix-port.patch b/usr.bin/indent/minix-port.patch new file mode 100644 index 000000000..e69de29bb diff --git a/usr.bin/indent/parse.c b/usr.bin/indent/parse.c new file mode 100644 index 000000000..1f30c71b1 --- /dev/null +++ b/usr.bin/indent/parse.c @@ -0,0 +1,360 @@ +/* $NetBSD: parse.c,v 1.7 2003/08/07 11:14:09 agc Exp $ */ + +/* + * 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. 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. + */ + +/* + * Copyright (c) 1976 Board of Trustees of the University of Illinois. + * Copyright (c) 1985 Sun Microsystems, Inc. + * 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. + */ + +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/6/93"; +#else +__RCSID("$NetBSD: parse.c,v 1.7 2003/08/07 11:14:09 agc Exp $"); +#endif +#endif /* not lint */ + +#include +#include "indent_globs.h" +#include "indent_codes.h" + +/* tk: the code for the construct scanned */ +void +parse(int tk) +{ + 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; + /* 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 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 ..." */ + ps.i_l_follow = ps.il[ps.tos]; + 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; + 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; + } + + break; + + case elselit: /* scanned an else */ + + if (ps.p_stack[ps.tos] != ifhead) + diag(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; + } + break; + + case rbrace: /* scanned a } */ + /* stack should have or */ + if (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 + diag(1, "Stmt 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; + 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 */ + diag(1, "Unknown code to parser"); + return; + + + } /* end of switch */ + + 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 +} +/* + * 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 | +\*----------------------------------------------*/ +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]; + + 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.p_stack[--ps.tos] = stmt; + break; + } else + return; + + default: /* anything else on top */ + return; + + } + } +} diff --git a/usr.bin/indent/pr_comment.c b/usr.bin/indent/pr_comment.c new file mode 100644 index 000000000..10f8d38c8 --- /dev/null +++ b/usr.bin/indent/pr_comment.c @@ -0,0 +1,461 @@ +/* $NetBSD: pr_comment.c,v 1.9 2003/08/07 11:14:09 agc Exp $ */ + +/* + * 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. 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. + */ + +/* + * Copyright (c) 1976 Board of Trustees of the University of Illinois. + * Copyright (c) 1985 Sun Microsystems, Inc. + * 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. + */ + +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)pr_comment.c 8.1 (Berkeley) 6/6/93"; +#else +__RCSID("$NetBSD: pr_comment.c,v 1.9 2003/08/07 11:14:09 agc Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include +#include "indent_globs.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 unix_comment; /* tri-state variable used to decide if it is + * a unix-style comment. 0 means only blanks + * since start, 1 means regular style comment, + * 2 means unix style comment */ + int break_delim = comment_delimiter_on_blankline; + int l_just_saw_decl = ps.just_saw_decl; + /* + * int ps.last_nl = 0; / * true iff the last significant thing + * weve seen is a newline + */ + int one_liner = 1; /* true iff this comment is a one-liner */ + adj_max_col = max_col; + ps.just_saw_decl = 0; + last_bl = 0; /* 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 */ + unix_comment = 1; /* set flag to let us figure out if there is a + * unix-style comment ** DISABLED: use 0 to + * reenable this hack! */ + + /* Figure where to align and how to treat the comment */ + + if (ps.col_1 && !format_col1_comments) { /* if comment starts in + * column 1 it should + * not be touched */ + ps.box_com = true; + ps.com_col = 1; + } else { + if (*buf_ptr == '-' || *buf_ptr == '*' || *buf_ptr == '\n') { + ps.box_com = true; /* a comment with a '-', '*' + * or newline immediately + * after the start comment is + * assumed to be a boxed + * comment */ + break_delim = 0; + } + 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; + if (ps.com_col <= 1) + ps.com_col = 1 + !format_col1_comments; + } else { + int target_col; + break_delim = 0; + 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; + if (ps.com_col < target_col) + ps.com_col = ((target_col + 7) & ~7) + 1; + if (ps.com_col + 24 > adj_max_col) + adj_max_col = ps.com_col + 24; + } + } + if (ps.box_com) { + buf_ptr[-2] = 0; + ps.n_comment_delta = 1 - count_spaces(1, in_buffer); + buf_ptr[-2] = '/'; + } else { + ps.n_comment_delta = 0; + while (*buf_ptr == ' ' || *buf_ptr == '\t') + buf_ptr++; + } + ps.comment_delta = 0; + *e_com++ = '/'; /* put '/' + '*' into buffer */ + *e_com++ = '*'; + if (*buf_ptr != ' ' && !ps.box_com) + *e_com++ = ' '; + + *e_com = '\0'; + if (troff) { + now_col = 1; + adj_max_col = 80; + } else + now_col = count_spaces(ps.com_col, s_com); /* figure what column we + * would be in if we + * printed the comment + * now */ + + /* Start to copy the comment */ + + while (1) { /* this loop will go until the comment is + * copied */ + if (!iscntrl((unsigned char)*buf_ptr) && *buf_ptr != '*') + ps.last_nl = 0; + CHECK_SIZE_COM; + switch (*buf_ptr) { /* this checks for various spcl cases */ + case 014: /* check for a form feed */ + 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 = 0; + *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"); + *e_com = '\0'; + dump_line(); + return; + } + one_liner = 0; + 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++ = ' '; + *e_com++ = ' '; + } + *e_com = '\0'; + if (!ps.box_com && e_com - s_com > 3) { + if (break_delim == 1 && s_com[0] == '/' + && s_com[1] == '*' && s_com[2] == ' ') { + char *t = e_com; + break_delim = 2; + e_com = s_com + 2; + *e_com = 0; + if (blanklines_before_blockcomments) + prefix_blankline_requested = 1; + dump_line(); + e_com = t; + s_com[0] = s_com[1] = s_com[2] = ' '; + } + dump_line(); + CHECK_SIZE_COM; + *e_com++ = ' '; + *e_com++ = ' '; + } + dump_line(); + now_col = ps.com_col; + } else { + ps.last_nl = 1; + if (unix_comment != 1) { /* we not are in + * unix_style comment */ + if (unix_comment == 0 && s_code == e_code) { + /* + * if it is a UNIX-style comment, ignore the + * requirement that previous line be blank for + * unindention + */ + ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1; + if (ps.com_col <= 1) + ps.com_col = 2; + } + unix_comment = 2; /* permanently remember + * that we are in this + * type of comment */ + dump_line(); + ++line_no; + now_col = ps.com_col; + *e_com++ = ' '; + /* + * fix so that the star at the start of the line will line + * up + */ + do /* flush leading white space */ + if (++buf_ptr >= buf_end) + fill_buffer(); + while (*buf_ptr == ' ' || *buf_ptr == '\t'); + break; + } + 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; + CHECK_SIZE_COM; + *e_com++ = ' '; + ++now_col; + } + } + ++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(); + + if (unix_comment == 0) /* set flag to show we are not + * in unix-style comment */ + unix_comment = 1; + + if (*buf_ptr == '/') { /* it is the end!!! */ + end_of_comment: + if (++buf_ptr >= buf_end) + fill_buffer(); + + if (*(e_com - 1) != ' ' && !ps.box_com) { /* insure blank before + * end */ + *e_com++ = ' '; + ++now_col; + } + if (break_delim == 1 && !one_liner && s_com[0] == '/' + && s_com[1] == '*' && s_com[2] == ' ') { + char *t = e_com; + break_delim = 2; + e_com = s_com + 2; + *e_com = 0; + if (blanklines_before_blockcomments) + prefix_blankline_requested = 1; + dump_line(); + e_com = t; + s_com[0] = s_com[1] = s_com[2] = ' '; + } + if (break_delim == 2 && e_com > s_com + 3 + /* now_col > adj_max_col - 2 && !ps.box_com */ ) { + *e_com = '\0'; + dump_line(); + now_col = ps.com_col; + } + CHECK_SIZE_COM; + *e_com++ = '*'; + *e_com++ = '/'; + *e_com = '\0'; + ps.just_saw_decl = l_just_saw_decl; + return; + } else {/* handle isolated '*' */ + *e_com++ = '*'; + ++now_col; + } + break; + default: /* we have a random char */ + if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t') + unix_comment = 1; /* we are not in + * unix-style comment */ + + *e_com = *buf_ptr++; + if (buf_ptr >= buf_end) + fill_buffer(); + + if (*e_com == '\t') /* keep track of column */ + now_col = ((now_col - 1) & tabmask) + tabsize + 1; + else + if (*e_com == '\b') /* this is a backspace */ + --now_col; + else + ++now_col; + + if (*e_com == ' ' || *e_com == '\t') + last_bl = e_com; + /* remember we saw a blank */ + + ++e_com; + if (now_col > adj_max_col && !ps.box_com && unix_comment == 1 + && !iscntrl((unsigned char)e_com[-1]) + && !isblank((unsigned char)e_com[-1])) { + /* + * the comment is too long, it must be broken up + */ + if (break_delim == 1 && s_com[0] == '/' + && s_com[1] == '*' && s_com[2] == ' ') { + char *t = e_com; + break_delim = 2; + e_com = s_com + 2; + *e_com = 0; + if (blanklines_before_blockcomments) + prefix_blankline_requested = 1; + dump_line(); + e_com = t; + s_com[0] = s_com[1] = s_com[2] = ' '; + } + if (last_bl == 0) { /* we have seen no + * blanks */ + last_bl = e_com; /* fake it */ + *e_com++ = ' '; + } + *e_com = '\0'; /* print what we have */ + *last_bl = '\0'; + while (last_bl > s_com && iscntrl((unsigned char)last_bl[-1]) ) + *--last_bl = 0; + e_com = last_bl; + dump_line(); + + *e_com++ = ' '; /* add blanks for continuation */ + *e_com++ = ' '; + *e_com++ = ' '; + + t_ptr = last_bl + 1; + last_bl = 0; + if (t_ptr >= e_com) { + while (*t_ptr == ' ' || *t_ptr == '\t') + t_ptr++; + while (*t_ptr != '\0') { /* move unprinted part + * of comment down in + * buffer */ + if (*t_ptr == ' ' || *t_ptr == '\t') + last_bl = e_com; + *e_com++ = *t_ptr++; + } + } + *e_com = '\0'; + now_col = count_spaces(ps.com_col, s_com); /* recompute current + * position */ + } + break; + } + } +} -- 2.44.0