home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume21
/
indent
/
part03
< prev
next >
Wrap
Text File
|
1991-08-07
|
33KB
|
1,104 lines
Newsgroups: comp.sources.misc,comp.lang.c++
From: Benson I. Margulies <benson@odi.com>
Subject: v21i100: indent - BSD Indent with C++ support, Part03/03
Message-ID: <1991Aug8.015940.3376@sparky.IMD.Sterling.COM>
X-Md4-Signature: 64faffc46f51124e951fdad0a2b3ee85
Date: Thu, 8 Aug 1991 01:59:40 GMT
Approved: kent@sparky.imd.sterling.com
Submitted-by: Benson I. Margulies <benson@odi.com>
Posting-number: Volume 21, Issue 100
Archive-name: indent/part03
Environment: UNIX, C++
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# Contents: indent/args.c indent/parse.c indent/pr_comment.c
# Wrapped by kent@sparky on Wed Aug 7 19:44:13 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 3 (of 3)."'
if test -f 'indent/args.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'indent/args.c'\"
else
echo shar: Extracting \"'indent/args.c'\" \(8848 characters\)
sed "s/^X//" >'indent/args.c' <<'END_OF_FILE'
X/*
X * Copyright (c) 1985 Sun Microsystems, Inc.
X * Copyright (c) 1980 The Regents of the University of California.
X * Copyright (c) 1976 Board of Trustees of the University of Illinois.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley, the University of Illinois,
X * Urbana, and Sun Microsystems, Inc. The name of either University
X * or Sun Microsystems may not be used to endorse or promote products
X * derived from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)args.c 5.6 (Berkeley) 9/15/88";
X#endif /* not lint */
X
X/*
X * Argument scanning and profile reading code. Default parameters are set
X * here as well.
X */
X
X#include "indent_globs.h"
X#include <sys/types.h>
X#include <ctype.h>
X
Xchar *getenv(), *index();
X
X/* profile types */
X#define PRO_SPECIAL 1 /* special case */
X#define PRO_BOOL 2 /* boolean */
X#define PRO_INT 3 /* integer */
X#define PRO_FONT 4 /* troff font */
X
X/* profile specials for booleans */
X#define ON 1 /* turn it on */
X#define OFF 0 /* turn it off */
X
X/* profile specials for specials */
X#define IGN 1 /* ignore it */
X#define CLI 2 /* case label indent (float) */
X#define STDIN 3 /* use stdin */
X#define KEY 4 /* type (keyword) */
X#define CCI 5 /* case code indent (float) */
X
X/*
X * N.B.: because of the way the table here is scanned, options whose names are
X * substrings of other options must occur later; that is, with -lp vs -l, -lp
X * must be first. Also, while (most) booleans occur more than once, the last
X * default value is the one actually assigned.
X */
Xstruct pro {
X char *p_name; /* name, eg -bl, -cli */
X int p_type; /* type (int, bool, special) */
X int p_default; /* the default value (if int) */
X int p_special; /* depends on type */
X int *p_obj; /* the associated variable */
X} pro[] = {
X
X "T", PRO_SPECIAL, 0, KEY, 0,
X "bacc", PRO_BOOL, false, ON, &blanklines_around_conditional_compilation,
X "badp", PRO_BOOL, false, ON, &blanklines_after_declarations_at_proctop,
X "bad", PRO_BOOL, false, ON, &blanklines_after_declarations,
X "bap", PRO_BOOL, false, ON, &blanklines_after_procs,
X "bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments,
X "bc", PRO_BOOL, true, OFF, &ps.leave_comma,
X "bl", PRO_BOOL, false, OFF, &btype_2,
X "brr", PRO_BOOL, false, ON, &btype_3,
X "br", PRO_BOOL, true, ON, &btype_2,
X "bs", PRO_BOOL, false, ON, &Bill_Shannon,
X "cdb", PRO_BOOL, true, ON, &comment_delimiter_on_blankline,
X "cd", PRO_INT, 0, 0, &ps.decl_com_ind,
X "ce", PRO_BOOL, true, ON, &cuddle_else,
X "ci", PRO_INT, 0, 0, &continuation_indent,
X "cli", PRO_SPECIAL, 0, CLI, 0,
X "cci", PRO_SPECIAL, 0, CCI, 0,
X "c", PRO_INT, 33, 0, &ps.com_ind,
X "di", PRO_INT, 16, 0, &ps.decl_indent,
X "dj", PRO_BOOL, false, ON, &ps.ljust_decl,
X "d", PRO_INT, 0, 0, &ps.unindent_displace,
X "eei", PRO_BOOL, false, ON, &extra_expression_indent,
X "ei", PRO_BOOL, true, ON, &ps.else_if,
X "fbc", PRO_FONT, 0, 0, (int *) &blkcomf,
X "fbx", PRO_FONT, 0, 0, (int *) &boxcomf,
X "fb", PRO_FONT, 0, 0, (int *) &bodyf,
X "fc1", PRO_BOOL, true, ON, &format_col1_comments,
X "fc", PRO_FONT, 0, 0, (int *) &scomf,
X "fk", PRO_FONT, 0, 0, (int *) &keywordf,
X "fs", PRO_FONT, 0, 0, (int *) &stringf,
X "ip", PRO_BOOL, true, ON, &ps.indent_parameters,
X "i", PRO_INT, 8, 0, &ps.ind_size,
X "lc", PRO_INT, 0, 0, &block_comment_max_col,
X "lp", PRO_BOOL, true, ON, &lineup_to_parens,
X "l", PRO_INT, 78, 0, &max_col,
X "nbacc", PRO_BOOL, false, OFF, &blanklines_around_conditional_compilation,
X "nbadp", PRO_BOOL, false, OFF, &blanklines_after_declarations_at_proctop,
X "nbad", PRO_BOOL, false, OFF, &blanklines_after_declarations,
X "nbap", PRO_BOOL, false, OFF, &blanklines_after_procs,
X "nbbb", PRO_BOOL, false, OFF, &blanklines_before_blockcomments,
X "nbc", PRO_BOOL, true, ON, &ps.leave_comma,
X "nbs", PRO_BOOL, false, OFF, &Bill_Shannon,
X "ncdb", PRO_BOOL, true, OFF, &comment_delimiter_on_blankline,
X "nce", PRO_BOOL, true, OFF, &cuddle_else,
X "ndj", PRO_BOOL, false, OFF, &ps.ljust_decl,
X "neei", PRO_BOOL, false, OFF, &extra_expression_indent,
X "nei", PRO_BOOL, true, OFF, &ps.else_if,
X "nfc1", PRO_BOOL, true, OFF, &format_col1_comments,
X "nip", PRO_BOOL, true, OFF, &ps.indent_parameters,
X "nlp", PRO_BOOL, true, OFF, &lineup_to_parens,
X "npcs", PRO_BOOL, false, OFF, &proc_calls_space,
X "npro", PRO_SPECIAL, 0, IGN, 0,
X "nprs", PRO_BOOL, false, OFF, &parens_space,
X "npsl", PRO_BOOL, true, OFF, &procnames_start_line,
X "nps", PRO_BOOL, false, OFF, &pointer_as_binop,
X "nsc", PRO_BOOL, true, OFF, &star_comment_cont,
X "nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines,
X "nv", PRO_BOOL, false, OFF, &verbose,
X "pcs", PRO_BOOL, false, ON, &proc_calls_space,
X "prs", PRO_BOOL, false, ON, &parens_space,
X "psl", PRO_BOOL, true, ON, &procnames_start_line,
X "ps", PRO_BOOL, false, ON, &pointer_as_binop,
X "sc", PRO_BOOL, true, ON, &star_comment_cont,
X "sob", PRO_BOOL, false, ON, &swallow_optional_blanklines,
X "st", PRO_SPECIAL, 0, STDIN, 0,
X "troff", PRO_BOOL, false, ON, &troff,
X "v", PRO_BOOL, false, ON, &verbose,
X "+", PRO_BOOL, false, ON, &cplus,
X /* whew! */
X 0, 0, 0, 0, 0
X};
X
X/*
X * set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments
X * given in these files.
X */
Xset_profile()
X{
X register FILE *f;
X char fname[BUFSIZ];
X static char prof[] = ".indent.pro";
X
X sprintf(fname, "%s/%s", getenv("HOME"), prof);
X if ((f = fopen(fname, "r")) != NULL) {
X scan_profile(f);
X (void) fclose(f);
X }
X if ((f = fopen(prof, "r")) != NULL) {
X scan_profile(f);
X (void) fclose(f);
X }
X}
X
Xscan_profile(f)
X register FILE *f;
X{
X register int i;
X register char *p;
X char buf[BUFSIZ];
X
X while (1) {
X for (p = buf; (i = getc(f)) != EOF && (*p = i) > ' '; ++p);
X if (p != buf) {
X *p++ = 0;
X if (verbose)
X printf("profile: %s\n", buf);
X set_option(buf);
X }
X else if (i == EOF)
X return;
X }
X}
X
Xchar *param_start;
X
Xeqin(s1, s2)
X register char *s1;
X register char *s2;
X{
X while (*s1) {
X if (*s1++ != *s2++)
X return (false);
X }
X param_start = s2;
X return (true);
X}
X
X/*
X * Set the defaults.
X */
Xset_defaults()
X{
X register struct pro *p;
X
X /*
X * Because ps.case_indent and ps.case_code_indent are floats, we can't
X * initialize them from the table:
X */
X ps.case_indent = 0.0; /* -cli0.0 */
X ps.case_code_indent = 1.0; /* -cci1.0 */
X for (p = pro; p->p_name; p++)
X if (p->p_type != PRO_SPECIAL && p->p_type != PRO_FONT)
X *p->p_obj = p->p_default;
X}
X
Xset_option(arg)
X register char *arg;
X{
X register struct pro *p;
X extern double atof();
X
X arg++; /* ignore leading "-" */
X for (p = pro; p->p_name; p++)
X if (*p->p_name == *arg && eqin(p->p_name, arg))
X goto found;
X fprintf(stderr, "indent: unknown parameter \"%s\"\n", arg - 1);
X exit(1);
Xfound:
X switch (p->p_type) {
X
X case PRO_SPECIAL:
X switch (p->p_special) {
X
X case IGN:
X break;
X
X case CLI:
X if (*param_start == 0)
X goto need_param;
X ps.case_indent = atof(param_start);
X break;
X
X case CCI:
X if (*param_start == 0)
X goto need_param;
X ps.case_code_indent = atof(param_start);
X break;
X
X case STDIN:
X if (input == 0)
X input = stdin;
X if (output == 0)
X output = stdout;
X break;
X
X case KEY:
X if (*param_start == 0)
X goto need_param;
X {
X register char *str = (char *) malloc(strlen(param_start) + 1);
X strcpy(str, param_start);
X addkey(str, 4);
X }
X break;
X
X default:
X fprintf(stderr, "\
Xindent: set_option: internal error: p_special %d\n", p->p_special);
X exit(1);
X }
X break;
X
X case PRO_BOOL:
X if (p->p_special == OFF)
X *p->p_obj = false;
X else
X *p->p_obj = true;
X break;
X
X case PRO_INT:
X if (*param_start == 0) {
X need_param:
X fprintf(stderr, "indent: ``%s'' requires a parameter\n",
X arg - 1);
X exit(1);
X }
X *p->p_obj = atoi(param_start);
X break;
X
X case PRO_FONT:
X parsefont((struct fstate *) p->p_obj, param_start);
X break;
X
X default:
X fprintf(stderr, "indent: set_option: internal error: p_type %d\n",
X p->p_type);
X exit(1);
X }
X}
END_OF_FILE
if test 8848 -ne `wc -c <'indent/args.c'`; then
echo shar: \"'indent/args.c'\" unpacked with wrong size!
fi
# end of 'indent/args.c'
fi
if test -f 'indent/parse.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'indent/parse.c'\"
else
echo shar: Extracting \"'indent/parse.c'\" \(8434 characters\)
sed "s/^X//" >'indent/parse.c' <<'END_OF_FILE'
X/*
X * Copyright (c) 1985 Sun Microsystems, Inc.
X * Copyright (c) 1980 The Regents of the University of California.
X * Copyright (c) 1976 Board of Trustees of the University of Illinois.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley, the University of Illinois,
X * Urbana, and Sun Microsystems, Inc. The name of either University
X * or Sun Microsystems may not be used to endorse or promote products
X * derived from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)parse.c 5.8 (Berkeley) 9/15/88";
X#endif /* not lint */
X
X#include "./indent_globs.h"
X#include "./indent_codes.h"
X
X
X
X
Xparse(tk)
X int tk; /* the code for the construct scanned */
X{
X int i;
X
X#ifdef debug
X printf("%2d - %s\n", tk, token);
X#endif
X
X while (ps.p_stack[ps.tos] == ifhead && tk != elselit) {
X /* true if we have an if without an else */
X ps.p_stack[ps.tos] = stmt; /* apply the if(..) stmt ::= stmt
X * reduction */
X reduce(); /* see if this allows any reduction */
X }
X
X
X switch (tk) { /* go on and figure out what to do with the
X * input */
X
X case decl: /* scanned a declaration word */
X ps.search_brace = btype_2 && !btype_3;
X /* indicate that following brace should be on same line */
X if (ps.p_stack[ps.tos] != decl) { /* only put one declaration
X * onto stack */
X break_comma = true; /* while in declaration, newline should be
X * forced after comma */
X ps.p_stack[++ps.tos] = decl;
X ps.il[ps.tos] = ps.i_l_follow;
X
X if (ps.ljust_decl) {/* only do if we want left justified
X * declarations */
X ps.ind_level = 0;
X for (i = ps.tos - 1; i > 0; --i)
X if (ps.p_stack[i] == decl)
X ++ps.ind_level; /* indentation is number of
X * declaration levels deep we are */
X ps.i_l_follow = ps.ind_level;
X }
X }
X break;
X
X case ifstmt: /* scanned if (...) */
X if (ps.p_stack[ps.tos] == elsehead && ps.else_if) /* "else if ..." */
X ps.i_l_follow = ps.il[ps.tos];
X case dolit: /* 'do' */
X case forstmt: /* for (...) */
X ps.p_stack[++ps.tos] = tk;
X ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
X ++ps.i_l_follow; /* subsequent statements should be indented 1 */
X ps.search_brace = btype_2 && !btype_3;
X break;
X
X case lbrace: /* scanned { */
X break_comma = false; /* don't break comma in an initial list */
X if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl
X || ps.p_stack[ps.tos] == stmtl)
X ++ps.i_l_follow; /* it is a random, isolated stmt group or a
X * declaration */
X else {
X if (s_code == e_code) {
X /*
X * only do this if there is nothing on the line
X */
X --ps.ind_level;
X /*
X * it is a group as part of a while, for, etc.
X */
X if (ps.p_stack[ps.tos] == swstmt && ps.case_indent >= 1 &&
X ps.case_code_indent >= 1)
X --ps.ind_level;
X /*
X * for a switch, brace should be two levels out from the code
X */
X }
X }
X
X ps.p_stack[++ps.tos] = lbrace;
X ps.il[ps.tos] = ps.ind_level;
X ps.p_stack[++ps.tos] = stmt;
X /* allow null stmt between braces */
X ps.il[ps.tos] = ps.i_l_follow;
X break;
X
X case whilestmt: /* scanned while (...) */
X if (ps.p_stack[ps.tos] == dohead) {
X /* it is matched with do stmt */
X ps.ind_level = ps.i_l_follow = ps.il[ps.tos];
X ps.p_stack[++ps.tos] = whilestmt;
X ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
X }
X else { /* it is a while loop */
X ps.p_stack[++ps.tos] = whilestmt;
X ps.il[ps.tos] = ps.i_l_follow;
X ++ps.i_l_follow;
X ps.search_brace = btype_2 && !btype_3;
X }
X
X break;
X
X case elselit: /* scanned an else */
X
X if (ps.p_stack[ps.tos] != ifhead)
X diag(1, "Unmatched 'else'");
X else {
X ps.ind_level = ps.il[ps.tos]; /* indentation for else should
X * be same as for if */
X ps.i_l_follow = ps.ind_level + 1; /* everything following should
X * be in 1 level */
X ps.p_stack[ps.tos] = elsehead;
X /* remember if with else */
X ps.search_brace = (btype_2 && !btype_3) | ps.else_if;
X }
X break;
X
X case rbrace: /* scanned a } */
X /* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */
X if (ps.p_stack[ps.tos - 1] == lbrace) {
X if (btype_3)
X ps.i_l_follow = ps.il[--ps.tos];
X else
X ps.ind_level = ps.i_l_follow = ps.il[--ps.tos];
X ps.p_stack[ps.tos] = stmt;
X }
X else
X diag(1, "Stmt nesting error.");
X break;
X
X case swstmt: /* had switch (...) */
X ps.p_stack[++ps.tos] = swstmt;
X ps.cstk[ps.tos] = case_ind;
X /* save current case indent level */
X ps.il[ps.tos] = ps.i_l_follow;
X case_ind = ps.i_l_follow + ps.case_indent;
X /*
X * cases should be one level down from switch
X */
X ps.i_l_follow += ps.case_indent + ps.case_code_indent;
X /*
X * statements should be two levels in
X */
X ps.search_brace = btype_2 && !btype_3;
X break;
X
X case semicolon: /* this indicates a simple stmt */
X break_comma = false; /* turn off flag to break after commas in a
X * declaration */
X ps.p_stack[++ps.tos] = stmt;
X ps.il[ps.tos] = ps.ind_level;
X break;
X
X default: /* this is an error */
X diag(1, "Unknown code to parser");
X return;
X
X
X } /* end of switch */
X
X reduce(); /* see if any reduction can be done */
X
X#ifdef debug
X for (i = 1; i <= ps.tos; ++i)
X printf("(%d %d)", ps.p_stack[i], ps.il[i]);
X printf("\n");
X#endif
X
X return;
X}
X
X/*
X * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
X *
X * All rights reserved
X *
X *
X * NAME: reduce
X *
X * FUNCTION: Implements the reduce part of the parsing algorithm
X *
X * ALGORITHM: The following reductions are done. Reductions are repeated until
X * no more are possible.
X *
X * Old TOS New TOS <stmt> <stmt> <stmtl> <stmtl> <stmt> <stmtl> do
X * <stmt> "dostmt" if <stmt> "ifstmt" switch <stmt> <stmt> decl
X * <stmt> <stmt> "ifelse" <stmt> <stmt> for <stmt> <stmt> while
X * <stmt> <stmt> "dostmt" while <stmt>
X *
X * On each reduction, ps.i_l_follow (the indentation for the following line) is
X * set to the indentation level associated with the old TOS.
X *
X * PARAMETERS: None
X *
X * RETURNS: Nothing
X *
X * GLOBALS: ps.cstk ps.i_l_follow = ps.il ps.p_stack = ps.tos =
X *
X * CALLS: None
X *
X * CALLED BY: parse
X *
X * HISTORY: initial coding November 1976 D A Willcox of CAC
X *
X */
X/*----------------------------------------------*\
X| REDUCTION PHASE |
X\*----------------------------------------------*/
Xreduce()
X{
X
X register int i;
X
X for (;;) { /* keep looping until there is nothing left to
X * reduce */
X
X switch (ps.p_stack[ps.tos]) {
X
X case stmt:
X switch (ps.p_stack[ps.tos - 1]) {
X
X case stmt:
X case stmtl:
X /* stmtl stmt or stmt stmt */
X ps.p_stack[--ps.tos] = stmtl;
X break;
X
X case dolit: /* <do> <stmt> */
X ps.p_stack[--ps.tos] = dohead;
X ps.i_l_follow = ps.il[ps.tos];
X break;
X
X case ifstmt:
X /* <if> <stmt> */
X ps.p_stack[--ps.tos] = ifhead;
X for (i = ps.tos - 1;
X (
X ps.p_stack[i] != stmt
X &&
X ps.p_stack[i] != stmtl
X &&
X ps.p_stack[i] != lbrace
X );
X --i);
X ps.i_l_follow = ps.il[i];
X /*
X * for the time being, we will assume that there is no else on
X * this if, and set the indentation level accordingly. If an
X * else is scanned, it will be fixed up later
X */
X break;
X
X case swstmt:
X /* <switch> <stmt> */
X case_ind = ps.cstk[ps.tos - 1];
X
X case decl: /* finish of a declaration */
X case elsehead:
X /* <<if> <stmt> else> <stmt> */
X case forstmt:
X /* <for> <stmt> */
X case whilestmt:
X /* <while> <stmt> */
X ps.p_stack[--ps.tos] = stmt;
X ps.i_l_follow = ps.il[ps.tos];
X break;
X
X default: /* <anything else> <stmt> */
X return;
X
X } /* end of section for <stmt> on top of stack */
X break;
X
X case whilestmt: /* while (...) on top */
X if (ps.p_stack[ps.tos - 1] == dohead) {
X /* it is termination of a do while */
X ps.p_stack[--ps.tos] = stmt;
X break;
X }
X else
X return;
X
X default: /* anything else on top */
X return;
X
X }
X }
X}
END_OF_FILE
if test 8434 -ne `wc -c <'indent/parse.c'`; then
echo shar: \"'indent/parse.c'\" unpacked with wrong size!
fi
# end of 'indent/parse.c'
fi
if test -f 'indent/pr_comment.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'indent/pr_comment.c'\"
else
echo shar: Extracting \"'indent/pr_comment.c'\" \(12009 characters\)
sed "s/^X//" >'indent/pr_comment.c' <<'END_OF_FILE'
X/*
X * Copyright (c) 1985 Sun Microsystems, Inc.
X * Copyright (c) 1980 The Regents of the University of California.
X * Copyright (c) 1976 Board of Trustees of the University of Illinois.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley, the University of Illinois,
X * Urbana, and Sun Microsystems, Inc. The name of either University
X * or Sun Microsystems may not be used to endorse or promote products
X * derived from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)pr_comment.c 5.9 (Berkeley) 9/15/88";
X#endif /* not lint */
X
X/*
X * NAME:
X * pr_comment
X *
X * FUNCTION:
X * This routine takes care of scanning and printing comments.
X *
X * ALGORITHM:
X * 1) Decide where the comment should be aligned, and if lines should
X * be broken.
X * 2) If lines should not be broken and filled, just copy up to end of
X * comment.
X * 3) If lines should be filled, then scan thru input_buffer copying
X * characters to com_buf. Remember where the last blank, tab, or
X * newline was. When line is filled, print up to last blank and
X * continue copying.
X *
X * HISTORY:
X * November 1976 D A Willcox of CAC Initial coding
X * 12/6/76 D A Willcox of CAC Modification to handle
X * UNIX-style comments
X *
X */
X
X/*
X * this routine processes comments. It makes an attempt to keep comments from
X * going over the max line length. If a line is too long, it moves everything
X * from the last blank to the next comment line. Blanks and tabs from the
X * beginning of the input line are removed
X */
X
X
X#include "indent_globs.h"
X
X
Xpr_comment()
X{
X int now_col; /* column we are in now */
X int adj_max_col; /* Adjusted max_col for when we decide to
X * spill comments over the right margin */
X char *last_bl; /* points to the last blank in the output
X * buffer */
X char *t_ptr; /* used for moving string */
X int unix_comment; /* tri-state variable used to decide if it is
X * a unix-style comment. 0 means only blanks
X * since /*, 1 means regular style comment, 2
X * means unix style comment */
X int break_delim = comment_delimiter_on_blankline;
X int l_just_saw_decl = ps.just_saw_decl;
X /*
X * int ps.last_nl = 0; /* true iff the last significant thing
X * weve seen is a newline
X */
X int one_liner = 1; /* true iff this comment is a one-liner */
X adj_max_col = max_col;
X ps.just_saw_decl = 0;
X last_bl = 0; /* no blanks found so far */
X ps.box_com = false; /* at first, assume that we are not in
X * a boxed comment or some other
X * comment that should not be touched */
X ++ps.out_coms; /* keep track of number of comments */
X unix_comment = 1; /* set flag to let us figure out if there is a
X * unix-style comment ** DISABLED: use 0 to
X * reenable this hack! */
X
X /* Figure where to align and how to treat the comment */
X
X if (ps.col_1 && !format_col1_comments) { /* if comment starts in column
X * 1 it should not be touched */
X ps.box_com = true;
X ps.com_col = 1;
X }
X else {
X if (*buf_ptr == '-' || *buf_ptr == '*') {
X ps.box_com = true; /* a comment with a '-' or '*' immediately
X * after the /* is assumed to be a boxed
X * comment */
X break_delim = 0;
X }
X if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) {
X /* klg: check only if this line is blank */
X /*
X * If this (*and previous lines are*) blank, dont put comment way
X * out at left
X */
X ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
X adj_max_col = block_comment_max_col;
X if (ps.com_col <= 1)
X ps.com_col = 1 + !format_col1_comments;
X }
X else {
X register target_col;
X break_delim = 0;
X if (s_code != e_code)
X target_col = count_spaces(compute_code_target(), s_code);
X else {
X target_col = 1;
X if (s_lab != e_lab)
X target_col = count_spaces(compute_label_target(), s_lab);
X }
X ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? ps.decl_com_ind : ps.com_ind;
X if (ps.com_col < target_col)
X ps.com_col = ((target_col + 7) & ~7) + 1;
X if (ps.com_col + 24 > adj_max_col)
X adj_max_col = ps.com_col + 24;
X }
X }
X if (ps.box_com) {
X buf_ptr[-2] = 0;
X ps.n_comment_delta = 1 - count_spaces(1, in_buffer);
X buf_ptr[-2] = '/';
X }
X else {
X ps.n_comment_delta = 0;
X while (*buf_ptr == ' ' || *buf_ptr == '\t')
X buf_ptr++;
X }
X ps.comment_delta = 0;
X *e_com++ = '/'; /* put '/*' into buffer */
X if (ps.cc_comment) /* (or '//') */
X *e_com++ = '/';
X else
X *e_com++ = '*';
X if (*buf_ptr != ' ' && !ps.box_com)
X *e_com++ = ' ';
X
X *e_com = '\0';
X if (troff) {
X now_col = 1;
X adj_max_col = 80;
X }
X else
X now_col = count_spaces(ps.com_col, s_com); /* figure what column we
X * would be in if we
X * printed the comment
X * now */
X
X /* Start to copy the comment */
X
X while (1) { /* this loop will go until the comment is
X * copied */
X if (*buf_ptr >= 040 && *buf_ptr != '*')
X ps.last_nl = 0;
X check_size(com);
X switch (*buf_ptr) { /* this checks for various spcl cases */
X case 014: /* check for a form feed */
X if (!ps.box_com) { /* in a text comment, break the line here */
X ps.use_ff = true;
X /* fix so dump_line uses a form feed */
X dump_line();
X last_bl = 0;
X *e_com++ = ' ';
X *e_com++ = '*';
X *e_com++ = ' ';
X while (*++buf_ptr == ' ' || *buf_ptr == '\t');
X }
X else {
X if (++buf_ptr >= buf_end)
X fill_buffer();
X *e_com++ = 014;
X }
X break;
X
X case '\n':
X if (ps.cc_comment) {
X *e_com = '\0';
X dump_line();
X ps.cc_comment = 0;
X ps.just_saw_decl = l_just_saw_decl; /* ?? */
X if (++buf_ptr >= buf_end) /* eat '\n' */
X fill_buffer();
X return;
X }
X if (had_eof) { /* check for unexpected eof */
X printf("Unterminated comment\n");
X *e_com = '\0';
X dump_line();
X return;
X }
X one_liner = 0;
X if (ps.box_com || ps.last_nl) { /* if this is a boxed comment,
X * we dont ignore the newline */
X if (s_com == e_com) {
X *e_com++ = ' ';
X *e_com++ = ' ';
X }
X *e_com = '\0';
X if (!ps.box_com && e_com - s_com > 3) {
X if (break_delim == 1 && s_com[0] == '/'
X && s_com[1] == '*' && s_com[2] == ' ') {
X char *t = e_com;
X break_delim = 2;
X e_com = s_com + 2;
X *e_com = 0;
X if (blanklines_before_blockcomments)
X prefix_blankline_requested = 1;
X dump_line();
X e_com = t;
X s_com[0] = s_com[1] = s_com[2] = ' ';
X }
X dump_line();
X check_size(com);
X *e_com++ = ' ';
X *e_com++ = ' ';
X }
X dump_line();
X now_col = ps.com_col;
X }
X else {
X ps.last_nl = 1;
X if (unix_comment != 1) { /* we not are in unix_style
X * comment */
X if (unix_comment == 0 && s_code == e_code) {
X /*
X * if it is a UNIX-style comment, ignore the
X * requirement that previous line be blank for
X * unindention
X */
X ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
X if (ps.com_col <= 1)
X ps.com_col = 2;
X }
X unix_comment = 2; /* permanently remember that we are in
X * this type of comment */
X dump_line();
X ++line_no;
X now_col = ps.com_col;
X *e_com++ = ' ';
X /*
X * fix so that the star at the start of the line will line
X * up
X */
X do /* flush leading white space */
X if (++buf_ptr >= buf_end)
X fill_buffer();
X while (*buf_ptr == ' ' || *buf_ptr == '\t');
X break;
X }
X if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t')
X last_bl = e_com - 1;
X /*
X * if there was a space at the end of the last line, remember
X * where it was
X */
X else { /* otherwise, insert one */
X last_bl = e_com;
X check_size(com);
X *e_com++ = ' ';
X ++now_col;
X }
X }
X ++line_no; /* keep track of input line number */
X if (!ps.box_com) {
X int nstar = 1;
X do { /* flush any blanks and/or tabs at start of
X * next line */
X if (++buf_ptr >= buf_end)
X fill_buffer();
X if (*buf_ptr == '*' && --nstar >= 0) {
X if (++buf_ptr >= buf_end)
X fill_buffer();
X if (*buf_ptr == '/')
X goto end_of_comment;
X }
X } while (*buf_ptr == ' ' || *buf_ptr == '\t');
X }
X else if (++buf_ptr >= buf_end)
X fill_buffer();
X break; /* end of case for newline */
X
X case '*': /* must check for possibility of being at end
X * of comment */
X if (++buf_ptr >= buf_end) /* get to next char after * */
X fill_buffer();
X
X if (unix_comment == 0) /* set flag to show we are not in
X * unix-style comment */
X unix_comment = 1;
X
X if (*buf_ptr == '/') { /* it is the end!!! */
X end_of_comment:
X if (++buf_ptr >= buf_end)
X fill_buffer();
X
X if (*(e_com - 1) != ' ' && !ps.box_com) { /* insure blank before
X * end */
X *e_com++ = ' ';
X ++now_col;
X }
X if (break_delim == 1 && !one_liner && s_com[0] == '/'
X && s_com[1] == '*' && s_com[2] == ' ') {
X char *t = e_com;
X break_delim = 2;
X e_com = s_com + 2;
X *e_com = 0;
X if (blanklines_before_blockcomments)
X prefix_blankline_requested = 1;
X dump_line();
X e_com = t;
X s_com[0] = s_com[1] = s_com[2] = ' ';
X }
X if (break_delim == 2 && e_com > s_com + 3
X /* now_col > adj_max_col - 2 && !ps.box_com */ ) {
X *e_com = '\0';
X dump_line();
X now_col = ps.com_col;
X }
X check_size(com);
X *e_com++ = '*';
X *e_com++ = '/';
X *e_com = '\0';
X ps.just_saw_decl = l_just_saw_decl;
X return;
X }
X else { /* handle isolated '*' */
X *e_com++ = '*';
X ++now_col;
X }
X break;
X default: /* we have a random char */
X if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t')
X unix_comment = 1; /* we are not in unix-style comment */
X
X *e_com = *buf_ptr++;
X if (buf_ptr >= buf_end)
X fill_buffer();
X
X if (*e_com == '\t') /* keep track of column */
X now_col = ((now_col - 1) & tabmask) + tabsize + 1;
X else if (*e_com == '\b') /* this is a backspace */
X --now_col;
X else
X ++now_col;
X
X if (*e_com == ' ' || *e_com == '\t')
X last_bl = e_com;
X /* remember we saw a blank */
X
X ++e_com;
X if (now_col > adj_max_col && !ps.box_com && unix_comment == 1 && e_com[-1] > ' ') {
X /*
X * the comment is too long, it must be broken up
X */
X if (break_delim == 1 && s_com[0] == '/'
X && s_com[1] == '*' && s_com[2] == ' ') {
X char *t = e_com;
X break_delim = 2;
X e_com = s_com + 2;
X *e_com = 0;
X if (blanklines_before_blockcomments)
X prefix_blankline_requested = 1;
X dump_line();
X e_com = t;
X s_com[0] = s_com[1] = s_com[2] = ' ';
X }
X if (last_bl == 0) { /* we have seen no blanks */
X last_bl = e_com; /* fake it */
X *e_com++ = ' ';
X }
X *e_com = '\0'; /* print what we have */
X *last_bl = '\0';
X while (last_bl > s_com && last_bl[-1] < 040)
X *--last_bl = 0;
X e_com = last_bl;
X dump_line();
X
X *e_com++ = ' '; /* add blanks for continuation */
X *e_com++ = ' ';
X *e_com++ = ' ';
X
X t_ptr = last_bl + 1;
X last_bl = 0;
X if (t_ptr >= e_com) {
X while (*t_ptr == ' ' || *t_ptr == '\t')
X t_ptr++;
X while (*t_ptr != '\0') { /* move unprinted part of
X * comment down in buffer */
X if (*t_ptr == ' ' || *t_ptr == '\t')
X last_bl = e_com;
X *e_com++ = *t_ptr++;
X }
X }
X *e_com = '\0';
X now_col = count_spaces(ps.com_col, s_com); /* recompute current
X * position */
X }
X break;
X }
X }
X}
END_OF_FILE
if test 12009 -ne `wc -c <'indent/pr_comment.c'`; then
echo shar: \"'indent/pr_comment.c'\" unpacked with wrong size!
fi
# end of 'indent/pr_comment.c'
fi
echo shar: End of archive 3 \(of 3\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 3 archives.
rm -f ark[1-9]isdone
else
echo You still must unpack the following archives:
echo " " ${MISSING}
fi
exit 0
exit 0 # Just in case...
--
Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD UUCP: uunet!sparky!kent
Phone: (402) 291-8300 FAX: (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.