[comp.sources.unix] v18i049: Indent, C reformatting program, Part01/03

rsalz@uunet.uu.net (Rich Salz) (03/22/89)

Submitted-by: Ozan Yigit <oz@nexus.yorku.ca>
Posting-number: Volume 18, Issue 49
Archive-name: indent/part01

[  Oz has done lots of work on cleaning up all the copyright questions,
   and fixing one or two bugs.  Kudo's to him.  He might appreciate
   fixes, and he might not. :-)  --r$  ]

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 3)."
# Contents:  indent indent/Makefile indent/args.c indent/indent.1
#   indent/indent_codes.h indent/indent_globs.h indent/parse.c
# Wrapped by oz@yunexus on Thu Mar  9 18:11:04 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test ! -d 'indent' ; then
    echo shar: Creating directory \"'indent'\"
    mkdir 'indent'
fi
if test -f 'indent/Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'indent/Makefile'\"
else
echo shar: Extracting \"'indent/Makefile'\" \(1414 characters\)
sed "s/^X//" >'indent/Makefile' <<'END_OF_FILE'
X#
X# Copyright (c) 1987 Regents of the University of California.
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 name of the
X# University may not be used to endorse or promote products derived
X# 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#	@(#)Makefile	5.9 (Berkeley) 9/15/88
X#
XCFLAGS=	-O
XLIBC=	/lib/libc.a
XSRCS=	indent.c io.c lexi.c parse.c pr_comment.c args.c
XOBJS=	indent.o io.o lexi.o parse.o pr_comment.o args.o
XMAN=	indent.0
X
Xall: indent
X
Xindent: ${OBJS} ${LIBC}
X	${CC} -o $@ ${CFLAGS} ${OBJS}
X
Xclean:
X	rm -f ${OBJS} core indent
X
Xcleandir: clean
X	rm -f ${MAN} tags .depend
X
Xdepend: ${SRCS}
X	mkdep ${CFLAGS} ${SRCS}
X
Xinstall: ${MAN}
X	install -s -o bin -g bin -m 755 indent ${DESTDIR}/usr/ucb/indent
X	install -c -o bin -g bin -m 444 indent.0 ${DESTDIR}/usr/man/cat1/indent.0
X
Xlint: ${SRCS}
X	lint ${CFLAGS} ${SRCS}
X
Xtags: ${SRCS}
X	ctags ${SRCS}
END_OF_FILE
if test 1414 -ne `wc -c <'indent/Makefile'`; then
    echo shar: \"'indent/Makefile'\" unpacked with wrong size!
fi
# end of 'indent/Makefile'
fi
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'\" \(8404 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
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, true, OFF, &btype_2,
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    "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    "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    "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    /* 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 is a float, we can't initialize it from the
X     * table:
X     */
X    ps.case_indent = 0.0;	/* -cli0.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 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 8404 -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/indent.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'indent/indent.1'\"
else
echo shar: Extracting \"'indent/indent.1'\" \(11633 characters\)
sed "s/^X//" >'indent/indent.1' <<'END_OF_FILE'
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.\" 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.\"	@(#)indent.1	6.5 (Berkeley) 9/15/88
X.\"
X
X.TH INDENT 1 "September 15, 1988
X.SH NAME
Xindent \- indent and format C program source
X.SH SYNOPSIS
X.in +\w'\fBindent \fR'u
X.ti -\w'\fBindent \fR'u
X\fBindent \fR [ \fIinput-file\fR [ \fIoutput-file\fR ] ]
X[\ \fB\-bad\fR\ |\ \fB\-nbad\fR\ ]
X[\ \fB\-bap\fR\ |\ \fB\-nbap\fR\ ]
X[\ \fB\-bbb\fR\ |\ \fB\-nbbb\fR\ ]
X[\ \fB\-bc\fR\ |\ \fB\-nbc\fR\ ]
X[\ \fB\-bl\fR\ ]
X[\ \fB\-br\fR\ ]
X[\ \fB\-c\fIn\fR\ ]
X[\ \fB\-cd\fIn\fR\ ]
X[\ \fB\-cdb\fR\ |\ \fB\-ncdb\fR\ ]
X[\ \fB\-ce\fR\ |\ \fB\-nce\fR\ ]
X[\ \fB\-ci\fIn\fR\ ]
X[\ \fB\-cli\fIn\fR\ ]
X[\ \fB\-d\fIn\fR\ ]
X[\ \fB\-di\fIn\fR\ ]
X[\ \fB\-fc1\fR\ |\ \fB\-nfc1\fR\ ]
X[\ \fB\-i\fIn\fR\ ]
X[\ \fB\-ip\fR\ |\ \fB\-nip\fR\ ]
X[\ \fB\-l\fIn\fR\ ]
X[\ \fB\-lc\fIn\fR\ ]
X[\ \fB\-lp\fR\ |\ \fB\-nlp\fR\ ]
X[\ \fB\-pcs\fR\ |\ \fB\-npcs\fR\ ]
X[\ \fB\-npro\fR\ ]
X[\ \fB\-psl\fR\ |\ \fB\-npsl\fR\ ]
X[\ \fB\-sc\fR\ |\ \fB\-nsc\fR\ ]
X[\ \fB\-sob\fR\ |\ \fB\-nsob\fR\ ]
X[\ \fB\-st\fR\ ]
X[\ \fB\-troff\fR\ ]
X[\ \fB\-v\fR\ |\ \fB\-nv\fR\ ]
X.SH DESCRIPTION
X.I Indent
Xis a \fBC\fR program formatter.  It reformats the \fBC\fR program in the
X\fIinput-file\fR according to the switches.  The switches which can be
Xspecified are described below. They may appear before or after the file
Xnames.
X.LP
X\fBNOTE\fP: If you only specify an \fIinput-file\fR, the formatting is
Xdone `in-place', that is, the formatted file is written back into
X.I input-file
Xand a backup copy of
X.I input-file
Xis written in the current directory.  If
X.I input-file
Xis named `/blah/blah/file', the backup file is named
X.RI file .BAK.
X.LP
XIf
X.I output-file
Xis specified,
X.I indent
Xchecks to make sure it is different from
X.IR input-file .
X.SH OPTIONS
X.LP
XThe options listed below control the formatting style imposed by
X.IR indent .
X.TP 15
X.BR \-bap , \-nbap
XIf
X.B \-bap
Xis specified, a blank line is forced after every procedure body.  Default:
X.B \-nbap.
X.TP 15
X.BR \-bad , \-nbad
XIf
X.B \-bad
Xis specified, a blank line is forced after every block of
Xdeclarations.  Default:  
X.B \-nbad.
X.TP 15
X.BR \-bbb , \-nbbb
XIf
X.B \-bbb
Xis specified, a blank line is forced before every block comment.  Default:
X.B \-nbbb.
X.TP 15
X.BR \-bc , \-nbc
XIf
X.B \-bc
Xis specified, then a newline is forced after each comma in a declaration. 
X.B \-nbc
Xturns off this option.  The default is
X.BR \-bc .
X.TP 15
X.BR \-br , \-bl
XSpecifying
X.B \-bl
Xlines up compound statements like this:
X.ne 4
X.nf
X.ft L
X    if (...)
X    {
X        code
X    }
X.ft R
X.fi
XSpecifying
X.B \-br
X(the default) makes them look like this:
X.ne 3
X.nf
X.ft L
X    if (...) {
X        code
X    }
X.ft R
X.fi
X.LP
X.TP 15
X.BI \-c n
XThe column in which comments on code start.  The default is 33.  
X.TP 15
X.BI \-cd n
XThe column in which comments on declarations start.  The default
Xis for these comments to start in the same column as those on code.
X.TP 15
X.BI \-cdb , \-ncdb
XEnables (disables) the placement of comment delimiters on blank lines.  With
Xthis option enabled, comments look like this:
X.nf
X.ft L
X.ne 3
X	/*
X	 * this is a comment
X	 */
X.ft R
X.fi
XRather than like this:
X.nf
X.ft L
X	/* this is a comment */
X.ft R
X.fi
XThis only affects block comments, not comments to the right of code. The default is
X.B \-cdb .
X.TP 15
X.BI \-ce , \-nce
XEnables (disables) forcing `else's to cuddle up to the immediatly preceeding
X`}'.  The default is
X.B \-ce .
X.TP 15
X.BI \-ci n
XSets the continuation indent to be \fIn\fR.  Continuation
Xlines will be indented that far from the beginning of the first line of the
Xstatement.  Parenthesized expressions have extra indentation added to
Xindicate the nesting, unless \fB\-lp\fR is in effect.
X\fB\-ci\fR defaults to the same value as \fB\-i\fR.
X.TP 15
X.BI \-cli n
XCauses case labels to be indented
X.I n
Xtab stops to the right of the containing \fBswitch\fR statement.
X\fB-cli0.5\fR causes case labels to be indented half a tab stop.  The
Xdefault is
X.B \-cli0 .
X.TP 15
X.BI \-d n
XControls the placement of comments which are not to the
Xright of code.  The default
X.B \-d1
Xmeans that such comments are placed one indentation level to the
Xleft of code.  Specifying
X.B \-d0
Xlines up these comments with the code.  See the section on comment
Xindentation below.
X.TP 15
X.BI \-di n
XSpecifies the indentation, in character positions, from a declaration keyword
Xto the following identifier.  The default is
X.B \-di16 .
X.if 0 \{.TP 15
X.BR \-dj , \-ndj
X.B \-dj
Xleft justifies declarations.
X.B \-ndj
Xindents declarations the same as code.  The default is
X.BR \-ndj .
X.TP 15
X.BI \-ei , \-nei
XEnables (disables) special
X.B else-if
Xprocessing.  If it's enabled,
X.BR if "s"
Xfollowing
X.BR else "s"
Xwill have the same indendation as the preceeding
X.B if
Xstatement.\}
X.TP 15
X.BI \-fc1 , \-nfc1
XEnables (disables) the formatting of comments that start in column 1.
XOften, comments whose leading `/' is in column 1 have been carefully
Xhand formatted by the programmer.  In such cases, \fB\-nfc1\fR should be
Xused.  The default is \fB\-fc1\fR.
X.TP 15
X.BI \-i n
XThe number of spaces for one indentation level.  The default is 4.
X.TP 15
X.BI \-ip , \-nip
XEnables (disables) the indentation of parameter declarations from the left
Xmargin.  The default is
X.B \-ip .
X.TP 15
X.BI \-l n
XMaximum length of an output line.  The default is 75.
X.TP 15
X.B \-npro
XCauses the profile files, `./.indent.pro' and `~/.indent.pro', to be ignored.
X.TP 15
X.BI \-lp , \-nlp
XLines up code surrounded by parenthesis in continuation lines.  If a line
Xhas a left paren which is not closed on that line, then continuation lines
Xwill be lined up to start at the character position just after the left
Xparen.  For example, here is how a piece of continued code looks with -nlp
Xin effect:
X.ne 2
X.nf
X.ft L
X    p1 = first_procedure(second_procedure(p2, p3),
X        third_procedure(p4, p5));
X.ft R
X.fi
X.ne 5
XWith \fB-lp\fR in effect (the default) the code looks somewhat clearer:
X.nf
X.ft L
X    p1 = first_procedure(second_procedure(p2, p3),
X                         third_procedure(p4, p5));
X.ft R
X.fi
X.ne 5
XInserting a couple more newlines we get:
X.nf
X.ft L
X    p1 = first_procedure(second_procedure(p2,
X                                          p3),
X                         third_procedure(p4,
X                                         p5));
X.ft R
X.fi
X.TP 15
X.B \-pcs , \-npcs
XIf true (\fB-pcs\fR) all procedure calls will have a space inserted between
Xthe name and the '('.  The default is 
X.B \-npcs
X.TP 15
X.B \-psl , \-npsl
XIf true (\fB-psl\fR) the names of procedures being defined are placed in
Xcolumn 1 \- their types, if any, will be left on the previous lines.  The
Xdefault is 
X.B -psl
X.TP 15
X.BI \-sc , \-nsc
XEnables (disables) the placement of asterisks (`*'s) at the left edge of all
Xcomments.
X.TP 15
X.BR \-sob , \-nsob
XIf
X.B \-sob
Xis specified, indent will swallow optional blank lines.  You can use this to
Xget rid of blank lines after declarations.  Default:
X.B \-nsob
X.TP 15
X.B \-st
XCauses
X.B indent
Xto take its input from stdin, and put its output to stdout.
X.TP 15
X.BI \-T typename
XAdds
X.I typename
Xto the list of type keywords.  Names accumulate:
X.B \-T
Xcan be specified more than once.  You need to specify all the typenames that
Xappear in your program that are defined by \fBtypedef\fRs \- nothing will be
Xharmed if you miss a few, but the program won't be formatted as nicely as
Xit should.  This sounds like a painful thing to have to do, but it's really
Xa symptom of a problem in C: \fBtypedef\fR causes a syntactic change in the
Xlaguage and \fIindent\fR can't find all \fBtypedef\fRs.
X.TP 15
X.B \-troff
XCauses
X.B indent
Xto format the program for processing by troff.  It will produce a fancy
Xlisting in much the same spirit as
X.BR vgrind.
XIf the output file is not specified, the default is standard output,
Xrather than formatting in place.
X.TP 15
X.BR \-v , \-nv
X.B \-v
Xturns on `verbose' mode,
X.B \-nv
Xturns it off.  When in verbose mode,
X.I indent
Xreports when it splits one line of input into two or more lines of output,
Xand gives some size statistics at completion. The default is
X.BR \-nv .
X.SH "FURTHER DESCRIPTION"
X.LP
XYou may set up your own `profile' of defaults to
X.I indent
Xby creating a file called
X.BI . indent . pro
Xin either your login directory or the current directory and including
Xwhatever switches you like.  A `.indent.pro' in the current directory takes
Xprecedence over the one in your login directory.  If
X.I indent
Xis run and a profile file exists, then it is read to set up the program's
Xdefaults.  Switches on the command line, though, always override profile
Xswitches.  The switches should be separated by spaces, tabs or newlines.
X.LP
X.B Comments
X.LP
X.IR "`Box' comments" .
X.I Indent
Xassumes that any comment with a dash or star immediately after the start of
Xcomment (that is, `/*\-' or `/**') is a comment surrounded by a box of stars.
XEach line of such a comment is left unchanged, except that its indentation
Xmay be adjusted to account for the change in indentation of the first line
Xof the comment.
X.LP
X.IR "Straight text" .
XAll other comments are treated as straight text.
X.I Indent
Xfits as many words (separated by blanks, tabs, or newlines) on a
Xline as possible.  Blank lines break paragraphs.
X.LP
X.B Comment indentation
X.LP
XIf a comment is on a line with code it is started in the `comment column',
Xwhich is set by the
X.BI \-c n
Xcommand line parameter.  Otherwise, the comment is started at
X.I n
Xindentation levels less than where code is currently being placed, where
X.I n
Xis specified by the
X.BI \-d n
Xcommand line parameter.  If the code on a line extends past the comment
Xcolumn, the comment starts further to the right, and the right margin may be
Xautomatically extended in extreme cases.
X.LP
X.B Preprocessor lines
X.LP
XIn general, \fIindent\fR leaves preprocessor lines alone.  The only
Xreformmatting that it will do is to straighten up trailing comments.  It
Xleaves imbedded comments alone.  Conditional compilation
X(\fB#ifdef...#endif\fR) is recognized and \fIindent\fR attempts to correctly
Xcompensate for the syntactic peculiarites introduced.
X.LP
X.B C syntax
X.LP
X\fIIndent\fR understands a substantial amount about the syntax of C, but it
Xhas a `forgiving' parser.  It attempts to cope with the usual sorts of
Xincomplete and misformed syntax.  In particular, the use of macros like:
X.nf
X.ft L
X        #define forever for(;;)
X.ft R
X.fi
Xis handled properly.
X.SH FILES
X.DT
X.br
X\&./.indent.pro	profile file
X.br
X.SH BUGS
X.I Indent
Xhas even more switches than \fIls\fR.
X
X.ne 5
XA common mistake that often causes grief is typing:
X.nf
X.ft L
X    indent *.c
X.ft R
X.fi
Xto the shell in an attempt to indent all the \fBC\fR programs in a directory.
XThis is probably a bug, not a feature.
END_OF_FILE
if test 11633 -ne `wc -c <'indent/indent.1'`; then
    echo shar: \"'indent/indent.1'\" unpacked with wrong size!
fi
# end of 'indent/indent.1'
fi
if test -f 'indent/indent_codes.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'indent/indent_codes.h'\"
else
echo shar: Extracting \"'indent/indent_codes.h'\" \(1688 characters\)
sed "s/^X//" >'indent/indent_codes.h' <<'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 *	@(#)indent_codes.h	5.6 (Berkeley) 9/15/88
X */
X
X#define newline		1
X#define lparen		2
X#define rparen		3
X#define unary_op	4
X#define binary_op	5
X#define postop		6
X#define question	7
X#define casestmt	8
X#define colon		9
X#define semicolon	10
X#define lbrace		11
X#define rbrace		12
X#define ident		13
X#define comma		14
X#define comment		15
X#define swstmt		16
X#define preesc		17
X#define form_feed	18
X#define decl		19
X#define sp_paren	20
X#define sp_nparen	21
X#define ifstmt		22
X#define whilestmt	23
X#define forstmt		24
X#define stmt		25
X#define stmtl		26
X#define elselit		27
X#define dolit		28
X#define dohead		29
X#define ifhead		30
X#define elsehead	31
X#define period		32
END_OF_FILE
if test 1688 -ne `wc -c <'indent/indent_codes.h'`; then
    echo shar: \"'indent/indent_codes.h'\" unpacked with wrong size!
fi
# end of 'indent/indent_codes.h'
fi
if test -f 'indent/indent_globs.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'indent/indent_globs.h'\"
else
echo shar: Extracting \"'indent/indent_globs.h'\" \(11268 characters\)
sed "s/^X//" >'indent/indent_globs.h' <<'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 *	@(#)indent_globs.h	5.7 (Berkeley) 9/15/88
X */
X
X#include <stdio.h>
X
X#define BACKSLASH '\\'
X#define bufsize 200		/* size of internal buffers */
X#define inp_bufs 600		/* size of input buffer */
X#define sc_size 5000		/* size of save_com buffer */
X#define label_offset 2		/* number of levels a label is placed to left
X				 * of code */
X
X#define tabsize 8		/* the size of a tab */
X#define tabmask 0177770		/* mask used when figuring length of lines
X				 * with tabs */
X
X
X#define false 0
X#define true  1
X
X
XFILE       *input;		/* the fid for the input file */
XFILE       *output;		/* the output file */
X
X#define check_size(name) \
X	if (e_/**/name >= l_/**/name) { \
X	    register nsize = l_/**/name-s_/**/name+400; \
X	    name/**/buf = (char *) realloc(name/**/buf, nsize); \
X	    e_/**/name = name/**/buf + (e_/**/name-s_/**/name) + 1; \
X	    l_/**/name = name/**/buf + nsize - 5; \
X	    s_/**/name = name/**/buf + 1; \
X	}
X
Xchar       *labbuf;		/* buffer for label */
Xchar       *s_lab;		/* start ... */
Xchar       *e_lab;		/* .. and end of stored label */
Xchar       *l_lab;		/* limit of label buffer */
X
Xchar       *codebuf;		/* buffer for code section */
Xchar       *s_code;		/* start ... */
Xchar       *e_code;		/* .. and end of stored code */
Xchar       *l_code;		/* limit of code section */
X
Xchar       *combuf;		/* buffer for comments */
Xchar       *s_com;		/* start ... */
Xchar       *e_com;		/* ... and end of stored comments */
Xchar       *l_com;		/* limit of comment buffer */
X
Xchar        in_buffer[inp_bufs];/* input buffer */
Xchar       *buf_ptr;		/* ptr to next character to be taken from
X				 * in_buffer */
Xchar       *buf_end;		/* ptr to first after last char in in_buffer */
X
Xchar        save_com[sc_size];	/* input text is saved here when looking for
X				 * the brace after an if, while, etc */
Xchar       *sc_end;		/* pointer into save_com buffer */
X
Xchar       *bp_save;		/* saved value of buf_ptr when taking input
X				 * from save_com */
Xchar       *be_save;		/* similarly saved value of buf_end */
X
Xchar        token[bufsize];	/* the last token scanned */
X
X
Xint         pointer_as_binop;
Xint         blanklines_after_declarations;
Xint         blanklines_before_blockcomments;
Xint         blanklines_after_procs;
Xint         blanklines_around_conditional_compilation;
Xint         swallow_optional_blanklines;
Xint         n_real_blanklines;
Xint         prefix_blankline_requested;
Xint         postfix_blankline_requested;
Xint         break_comma;	/* when true and not in parens, break after a
X				 * comma */
Xint         btype_2;		/* when true, brace should be on same line as
X				 * if, while, etc */
Xfloat       case_ind;		/* indentation level to be used for a "case
X				 * n:" */
Xint         code_lines;		/* count of lines with code */
Xint         had_eof;		/* set to true when input is exhausted */
Xint         line_no;		/* the current line number. */
Xint         max_col;		/* the maximum allowable line length */
Xint         verbose;		/* when true, non-essential error messages are
X				 * printed */
Xint         cuddle_else;	/* true if else should cuddle up to '}' */
Xint         star_comment_cont;	/* true iff comment continuation lines should
X				 * have stars at the beginning of each line. */
Xint         comment_delimiter_on_blankline;
Xint         troff;		/* true iff were generating troff input */
Xint         procnames_start_line;	/* if true, the names of procedures
X					 * being defined get placed in column
X					 * 1 (ie. a newline is placed between
X					 * the type of the procedure and its
X					 * name) */
Xint         proc_calls_space;	/* If true, procedure calls look like:
X				 * foo(bar) rather than foo (bar) */
Xint         format_col1_comments;	/* If comments which start in column 1
X					 * are to be magically reformatted
X					 * (just like comments that begin in
X					 * later columns) */
Xint         inhibit_formatting;	/* true if INDENT OFF is in effect */
Xint         suppress_blanklines;/* set iff following blanklines should be
X				 * suppressed */
Xint         continuation_indent;/* set to the indentation between the edge of
X				 * code and continuation lines */
Xint         lineup_to_parens;	/* if true, continued code within parens will
X				 * be lined up to the open paren */
Xint         Bill_Shannon;	/* true iff a blank should always be inserted
X				 * after sizeof */
Xint         blanklines_after_declarations_at_proctop;	/* This is vaguely
X							 * similar to
X							 * blanklines_after_decla
X							 * rations except that
X							 * it only applies to
X							 * the first set of
X							 * declarations in a
X							 * procedure (just after
X							 * the first '{') and it
X							 * causes a blank line
X							 * to be generated even
X							 * if there are no
X							 * declarations */
Xint         block_comment_max_col;
Xint         extra_expression_indent;	/* True if continuation lines from the
X					 * expression part of "if(e)",
X					 * "while(e)", "for(e;e;e)" should be
X					 * indented an extra tab stop so that
X					 * they don't conflict with the code
X					 * that follows */
X
X/* -troff font state information */
X
Xstruct fstate {
X    char        font[4];
X    char        size;
X    int         allcaps:1;
X};
Xchar       *chfont();
X
Xstruct fstate
X            keywordf,		/* keyword font */
X            stringf,		/* string font */
X            boxcomf,		/* Box comment font */
X            blkcomf,		/* Block comment font */
X            scomf,		/* Same line comment font */
X            bodyf;		/* major body font */
X
X
X#define STACKSIZE 150
X
Xstruct parser_state {
X    int         last_token;
X    struct fstate cfont;	/* Current font */
X    int         p_stack[STACKSIZE];	/* this is the parsers stack */
X    int         il[STACKSIZE];	/* this stack stores indentation levels */
X    float       cstk[STACKSIZE];/* used to store case stmt indentation levels */
X    int         box_com;	/* set to true when we are in a "boxed"
X				 * comment. In that case, the first non-blank
X				 * char should be lined up with the / in /* */
X    int         comment_delta,
X                n_comment_delta;
X    int         cast_mask;	/* indicates which close parens close off
X				 * casts */
X    int         sizeof_mask;	/* indicates which close parens close off
X				 * sizeof''s */
X    int         block_init;	/* true iff inside a block initialization */
X    int         block_init_level;	/* The level of brace nesting in an
X					 * initialization */
X    int         last_nl;	/* this is true if the last thing scanned was
X				 * a newline */
X    int         in_or_st;	/* Will be true iff there has been a
X				 * declarator (e.g. int or char) and no left
X				 * paren since the last semicolon. When true,
X				 * a '{' is starting a structure definition or
X				 * an initialization list */
X    int         bl_line;	/* set to 1 by dump_line if the line is blank */
X    int         col_1;		/* set to true if the last token started in
X				 * column 1 */
X    int         com_col;	/* this is the column in which the current
X				 * coment should start */
X    int         com_ind;	/* the column in which comments to the right
X				 * of code should start */
X    int         com_lines;	/* the number of lines with comments, set by
X				 * dump_line */
X    int         dec_nest;	/* current nesting level for structure or init */
X    int         decl_com_ind;	/* the column in which comments after
X				 * declarations should be put */
X    int         decl_on_line;	/* set to true if this line of code has part
X				 * of a declaration on it */
X    int         i_l_follow;	/* the level to which ind_level should be set
X				 * after the current line is printed */
X    int         in_decl;	/* set to true when we are in a declaration
X				 * stmt.  The processing of braces is then
X				 * slightly different */
X    int         in_stmt;	/* set to 1 while in a stmt */
X    int         ind_level;	/* the current indentation level */
X    int         ind_size;	/* the size of one indentation level */
X    int         ind_stmt;	/* set to 1 if next line should have an extra
X				 * indentation level because we are in the
X				 * middle of a stmt */
X    int         last_u_d;	/* set to true after scanning a token which
X				 * forces a following operator to be unary */
X    int         leave_comma;	/* if true, never break declarations after
X				 * commas */
X    int         ljust_decl;	/* true if declarations should be left
X				 * justified */
X    int         out_coms;	/* the number of comments processed, set by
X				 * pr_comment */
X    int         out_lines;	/* the number of lines written, set by
X				 * dump_line */
X    int         p_l_follow;	/* used to remember how to indent following
X				 * statement */
X    int         paren_level;	/* parenthesization level. used to indent
X				 * within stmts */
X    short       paren_indents[20];	/* column positions of each paren */
X    int         pcase;		/* set to 1 if the current line label is a
X				 * case.  It is printed differently from a
X				 * regular label */
X    int         search_brace;	/* set to true by parse when it is necessary
X				 * to buffer up all info up to the start of a
X				 * stmt after an if, while, etc */
X    int         unindent_displace;	/* comments not to the right of code
X					 * will be placed this many
X					 * indentation levels to the left of
X					 * code */
X    int         use_ff;		/* set to one if the current line should be
X				 * terminated with a form feed */
X    int         want_blank;	/* set to true when the following token should
X				 * be prefixed by a blank. (Said prefixing is
X				 * ignored in some cases.) */
X    int         else_if;	/* True iff else if pairs should be handled
X				 * specially */
X    int         decl_indent;	/* column to indent declared identifiers to */
X    int         its_a_keyword;
X    int         sizeof_keyword;
X    int         dumped_decl_indent;
X    float       case_indent;	/* The distance to indent case labels from the
X				 * switch statement */
X    int         in_parameter_declaration;
X    int         indent_parameters;
X    int         tos;		/* pointer to top of stack */
X    char        procname[100];	/* The name of the current procedure */
X    int         just_saw_decl;
X}           ps;
X
Xint         ifdef_level;
Xstruct parser_state state_stack[5];
Xstruct parser_state match_state[5];
END_OF_FILE
if test 11268 -ne `wc -c <'indent/indent_globs.h'`; then
    echo shar: \"'indent/indent_globs.h'\" unpacked with wrong size!
fi
# end of 'indent/indent_globs.h'
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'\" \(8276 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;
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;
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.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;
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 | 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	    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;	/* cases should be one
X							 * level down from
X							 * switch */
X	ps.i_l_follow += ps.case_indent + 1;	/* statements should be two
X						 * levels in */
X	ps.search_brace = btype_2;
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
echo shar: 1 control character may be missing from \"'indent/parse.c'\"
if test 8276 -ne `wc -c <'indent/parse.c'`; then
    echo shar: \"'indent/parse.c'\" unpacked with wrong size!
fi
# end of 'indent/parse.c'
fi
echo shar: End of archive 1 \(of 3\).
cp /dev/null ark1isdone
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 need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.