home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume21
/
indent
/
part02
< prev
next >
Wrap
Text File
|
1991-08-07
|
54KB
|
1,932 lines
Newsgroups: comp.sources.misc,comp.lang.c++
From: Benson I. Margulies <benson@odi.com>
Subject: v21i099: indent - BSD Indent with C++ support, Part02/03
Message-ID: <1991Aug8.015909.3312@sparky.IMD.Sterling.COM>
X-Md4-Signature: 3fb413b78ebfa59cd207a30fae98bbbf
Date: Thu, 8 Aug 1991 01:59:09 GMT
Approved: kent@sparky.imd.sterling.com
Submitted-by: Benson I. Margulies <benson@odi.com>
Posting-number: Volume 21, Issue 99
Archive-name: indent/part02
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/Makefile indent/README indent/indent.1
# indent/indent_codes.h indent/io.c indent/lexi.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 2 (of 3)."'
if test -f 'indent/Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'indent/Makefile'\"
else
echo shar: Extracting \"'indent/Makefile'\" \(1438 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 -DBSD #-DMAXPATHLEN=256
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 1438 -ne `wc -c <'indent/Makefile'`; then
echo shar: \"'indent/Makefile'\" unpacked with wrong size!
fi
# end of 'indent/Makefile'
fi
if test -f 'indent/README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'indent/README'\"
else
echo shar: Extracting \"'indent/README'\" \(291 characters\)
sed "s/^X//" >'indent/README' <<'END_OF_FILE'
XIndent is a C/C++ program formatter. It reformats the C/C++ program
Xin the input-file according to a long list of command line switches.
X
XThe original indent (part of the Berkeley Software Distribution) was
Xonly for C programs. It has since been modified to understand C++
Xsyntax as well.
END_OF_FILE
if test 291 -ne `wc -c <'indent/README'`; then
echo shar: \"'indent/README'\" unpacked with wrong size!
fi
# end of 'indent/README'
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'\" \(13352 characters\)
sed "s/^X//" >'indent/indent.1' <<'END_OF_FILE'
X.\" Copyright 1989 Object Design, Inc.
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.TH INDENT 1 "July 14, 1989
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\-brr\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\-cci\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\-prs\fR\ |\ \fB\-nprs\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[\ \fB-+\fR ]
X
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 , \-brr
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
XAnd specifying
X.B \-brr
Xmakes them look like this:
X.ne 3
X.nf
X.ft L
X if (...)
X {
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 \-cci n
XCauses case code to be indented
X.I n
Xtab stops to the right of the corresponding case label.
X\fB-cci0.5\fR causes case code to be indented half a tab stop. The
Xdefault is
X.B \-cci1 .
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 \-prs , \-nprs
XIf true (\fB-prs\fR) all parentheses will have a space inserted
Xafter the '(' and before the ')'. The default is
X.B \-nprs
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
Xlanguage 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.TP 15
X.B \-+
Xturns on support for C++. In c++ mode, :: is permited in identifiers,
XC++ keywords are supported, and class definition keywords
X(public, private, etc.) are set in column 2.
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 Special Comments
X.LP
X.I Indent
Xproduces and interprets some special comments.
XWhen indent cannot parse the source, it prints a message on standard error
Xand inserts a comment into the output of the form
X.nf
X.ft L
X /**INDENT** ErrorMessage */
X.ft R
X.fi
X.LP
X.I Indent
Xinterprets several special comments as directives.
XFirst, it makes no attempt to format lines containing the error comment
Xdescribed above.
X.LP
XSecond, lines of the form:
X.nf
X.ft L
X /* INDENT OFF */
Xor
X /* INDENT ON */
X.ft R
X.fi
Xdisable and re-enable indent formatting.
XAny amount of whitespace may replace the spaces shown in the examples.
X.LP
XThird,
X.I indent
Xallows formatting controls to be included in the source via comments of the form:
X.nf
X.ft L
X /* INDENT: arg1 arg2 arg3 ... arg4 */
X.ft R
X.fi
XThe arguments given are in the same syntax as the command line or profile file.
XFor example:
X.nf
X.ft L
X /* INDENT: -cli.25 -nfc1 */
X.ft R
X.fi
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 13352 -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'\" \(1786 characters\)
sed "s/^X//" >'indent/indent_codes.h' <<'END_OF_FILE'
X/*
X * Copyright 1989 Object Design, Inc.
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
X
X#define cc_commnt 33
X#define class 34
X#define privpub 35
END_OF_FILE
if test 1786 -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/io.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'indent/io.c'\"
else
echo shar: Extracting \"'indent/io.c'\" \(15511 characters\)
sed "s/^X//" >'indent/io.c' <<'END_OF_FILE'
X/*
X * Copyright 1989 Object Design, Inc.
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[] = "@(#)io.c 5.10 (Berkeley) 9/15/88";
X#endif /* not lint */
X
X#include "indent_globs.h"
X#include <ctype.h>
X
X
Xint comment_open;
Xstatic paren_target;
X
Xdump_line()
X{ /* dump_line is the routine that actually
X * effects the printing of the new source. It
X * prints the label section, followed by the
X * code section with the appropriate nesting
X * level, followed by any comments */
X register int cur_col,
X target_col;
X static not_first_line;
X
X if (ps.procname[0]) {
X if (troff) {
X if (comment_open) {
X comment_open = 0;
X fprintf(output, ".*/\n");
X }
X fprintf(output, ".Pr \"%s\"\n", ps.procname);
X }
X ps.ind_level = 0;
X ps.procname[0] = 0;
X }
X if (s_code == e_code && s_lab == e_lab && s_com == e_com) {
X if (suppress_blanklines > 0)
X suppress_blanklines--;
X else {
X ps.bl_line = true;
X n_real_blanklines++;
X }
X }
X else if (!inhibit_formatting) {
X suppress_blanklines = 0;
X ps.bl_line = false;
X if (prefix_blankline_requested && not_first_line)
X if (swallow_optional_blanklines) {
X if (n_real_blanklines == 1)
X n_real_blanklines = 0;
X }
X else {
X if (n_real_blanklines == 0)
X n_real_blanklines = 1;
X }
X while (--n_real_blanklines >= 0)
X putc('\n', output);
X n_real_blanklines = 0;
X if (ps.ind_level == 0) {
X if (!btype_3)
X ps.ind_stmt = 0; /* this is a class A kludge. dont do
X * additional statement indentation
X * if we are at bracket level 0 */
X else
X if (*s_code != '{')
X ps.ind_stmt = 0; /* this one is a class AA kludge:
X * defeat the class A kludge if
X * the statement is '{' */
X }
X
X if (e_lab != s_lab || e_code != s_code)
X ++code_lines; /* keep count of lines with code */
X
X
X if (e_lab != s_lab) { /* print lab, if any */
X if (comment_open) {
X comment_open = 0;
X fprintf(output, ".*/\n");
X }
X while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
X e_lab--;
X cur_col = pad_output(1, compute_label_target());
X fprintf(output, "%.*s", e_lab - s_lab, s_lab);
X cur_col = count_spaces(cur_col, s_lab);
X }
X else
X cur_col = 1; /* there is no label section */
X
X ps.pcase = false;
X
X if (s_code != e_code) { /* print code section, if any */
X register char *p;
X
X if (comment_open) {
X comment_open = 0;
X fprintf(output, ".*/\n");
X }
X target_col = compute_code_target();
X {
X register i;
X
X for (i = 0; i < ps.p_l_follow; i++)
X if (ps.paren_indents[i] >= 0)
X ps.paren_indents[i] = -(ps.paren_indents[i] + target_col);
X }
X cur_col = pad_output(cur_col, target_col);
X for (p = s_code; p < e_code; p++)
X if (*p == (char) 0200)
X fprintf(output, "%d", target_col * 7);
X else
X putc(*p, output);
X cur_col = count_spaces(cur_col, s_code);
X }
X if (s_com != e_com)
X if (troff) {
X int all_here = 0;
X register char *p;
X
X if (ps.cc_comment)
X all_here++;
X else if (e_com[-1] == '/' && e_com[-2] == '*')
X e_com -= 2, all_here++;
X while (e_com > s_com && e_com[-1] == ' ')
X e_com--;
X *e_com = 0;
X p = s_com;
X while (*p == ' ')
X p++;
X if (p[0] == '/' && (p[1] == '*' || p[1] == '/'))
X p += 2, all_here++;
X else if (p[0] == '*')
X p += p[1] == '/' ? 2 : 1;
X while (*p == ' ')
X p++;
X if (*p == 0)
X goto inhibit_newline;
X if (comment_open < 2 && ps.box_com) {
X comment_open = 0;
X fprintf(output, ".*/\n");
X }
X if (comment_open == 0) {
X if ('a' <= *p && *p <= 'z')
X *p = *p + 'A' - 'a';
X if (e_com - p < 50 && all_here == 2) {
X register char *follow = p;
X fprintf(output, "\n.nr C! \\w\1");
X while (follow < e_com) {
X switch (*follow) {
X case '\n':
X putc(' ', output);
X case 1:
X break;
X case '\\':
X putc('\\', output);
X default:
X putc(*follow, output);
X }
X follow++;
X }
X putc(1, output);
X }
X fprintf(output, "\n./* %dp %d %dp\n",
X ps.com_col * 7,
X (s_code != e_code || s_lab != e_lab) - ps.box_com,
X target_col * 7);
X }
X comment_open = 1 + ps.box_com;
X while (*p) {
X if (*p == BACKSLASH)
X putc(BACKSLASH, output);
X putc(*p++, output);
X }
X }
X else { /* print comment, if any */
X register target = ps.com_col;
X register char *com_st = s_com;
X
X target += ps.comment_delta;
X while (*com_st == '\t')
X com_st++, target += 8; /* ? */
X while (target <= 0)
X if (*com_st == ' ')
X target++, com_st++;
X else if (*com_st == '\t')
X target = ((target - 1) & ~7) + 9, com_st++;
X else
X target = 1;
X if (cur_col > target) { /* if comment cant fit on this line,
X * put it on next line */
X putc('\n', output);
X cur_col = 1;
X ++ps.out_lines;
X }
X while (e_com > com_st && isspace(e_com[-1]))
X e_com--;
X cur_col = pad_output(cur_col, target);
X if (!ps.box_com && !ps.cc_comment) {
X if (star_comment_cont && (com_st[1] != '*' || e_com <= com_st + 1))
X if (com_st[1] == ' ' && com_st[0] == ' ' && e_com > com_st + 1)
X com_st[1] = '*';
X else
X fwrite(" * ", com_st[0] == '\t' ? 2 : com_st[0] == '*' ? 1 : 3, 1, output);
X }
X fwrite(com_st, e_com - com_st, 1, output);
X ps.comment_delta = ps.n_comment_delta;
X cur_col = count_spaces(cur_col, com_st);
X ++ps.com_lines; /* count lines with comments */
X }
X if (ps.use_ff)
X putc('\014', output);
X else
X putc('\n', output);
Xinhibit_newline:
X ++ps.out_lines;
X if (ps.just_saw_decl == 1 && blanklines_after_declarations) {
X prefix_blankline_requested = 1;
X ps.just_saw_decl = 0;
X }
X else
X prefix_blankline_requested = postfix_blankline_requested;
X postfix_blankline_requested = 0;
X }
X ps.decl_on_line = ps.in_decl; /* if we are in the middle of a
X * declaration, remember that fact for
X * proper comment indentation */
X ps.ind_stmt = ps.in_stmt & ~ps.in_decl; /* next line should be
X * indented if we have not
X * completed this stmt and if
X * we are not in the middle of
X * a declaration */
X ps.use_ff = false;
X ps.dumped_decl_indent = 0;
X *(e_lab = s_lab) = '\0'; /* reset buffers */
X *(e_code = s_code) = '\0';
X *(e_com = s_com) = '\0';
X ps.ind_level = ps.i_l_follow;
X ps.paren_level = ps.p_l_follow;
X paren_target = -ps.paren_indents[ps.paren_level - 1];
X not_first_line = 1;
X return;
X};
X
Xcompute_code_target()
X{
X register target_col = ps.ind_size * ps.ind_level + 1;
X
X if (ps.paren_level)
X if (!lineup_to_parens)
X target_col += continuation_indent * ps.paren_level;
X else {
X register w;
X register t = paren_target;
X
X if ((w = count_spaces(t, s_code) - max_col) > 0
X && count_spaces(target_col, s_code) <= max_col) {
X t -= w + 1;
X if (t > target_col)
X target_col = t;
X }
X else
X target_col = t;
X }
X else if (ps.ind_stmt)
X target_col += continuation_indent;
X return target_col;
X}
X
Xcompute_label_target()
X{
X return
X ps.pcase ?
X (cplus && ps.in_decl) ? cplus_ppp_indent
X : (int) (case_ind * ps.ind_size) + 1
X : *s_lab == '#' ? 1
X : ps.ind_size * (ps.ind_level - label_offset) + 1;
X}
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: fill_buffer
X *
X * FUNCTION: Reads one block of input into input_buffer
X *
X * HISTORY: initial coding November 1976 D A Willcox of CAC 1/7/77 A
X * Willcox of CAC Added check for switch back to partly full input
X * buffer from temporary buffer
X *
X */
Xint
Xfill_buffer()
X{ /* this routine reads stuff from the input */
X register char *p;
X register int i;
X register FILE *f = input;
X
X if (bp_save != 0) { /* there is a partly filled input buffer left */
X buf_ptr = bp_save; /* dont read anything, just switch buffers */
X buf_end = be_save;
X bp_save = be_save = 0;
X if (buf_ptr < buf_end)
X return; /* only return if there is really something in
X * this buffer */
X }
X for (p = buf_ptr = in_buffer;;) {
X if ((i = getc(f)) == EOF) {
X *p++ = ' ';
X *p++ = '\n';
X had_eof = true;
X break;
X }
X *p++ = i;
X if (i == '\n')
X break;
X }
X buf_end = p;
X if (p[-2] == '/' && p[-3] == '*') {
X if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0)
X fill_buffer(); /* flush indent error message */
X else {
X int com = 0;
X
X p = in_buffer;
X while (*p == ' ' || *p == '\t')
X p++;
X if (*p == '/' && p[1] == '*') {
X p += 2;
X while (*p == ' ' || *p == '\t')
X p++;
X if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E'
X && p[4] == 'N' && p[5] == 'T') {
X p += 6;
X if(*p == ':') {
X#define MAX_SOURCE_ARG 100
X char argbuf[MAX_SOURCE_ARG]; /* how big can they get ... */
X char * a;
X p++; /* skip the : */
X /* since set_option changes flags, process pending stuff now */
X if (s_com != e_com || s_lab != e_lab || s_code != e_code)
X dump_line();
X while (1) {
X a = argbuf; /* accumulate an option */
X while (*p <= ' ') /* skip whitespace */
X p++;
X if(*p == '*') break;
X while (*p > ' ')
X *a++ = *p++;
X *a++ = '\0';
X set_option(argbuf);
X }
X goto End_Magic_Comment;
X }
X while (*p == ' ' || *p == '\t')
X p++;
X if (*p == '*')
X com = 1;
X else if (*p == 'O')
X if (*++p == 'N')
X p++, com = 1;
X else if (*p == 'F' && *++p == 'F')
X p++, com = 2;
X while (*p == ' ' || *p == '\t')
X p++;
X if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com) {
X if (s_com != e_com || s_lab != e_lab || s_code != e_code)
X dump_line();
X if (!(inhibit_formatting = com - 1)) {
X n_real_blanklines = 0;
X postfix_blankline_requested = 0;
X prefix_blankline_requested = 0;
X suppress_blanklines = 1;
X }
X }
X }
X }
X }
X }
XEnd_Magic_Comment:
X if (inhibit_formatting) {
X p = in_buffer;
X do
X putc(*p, output);
X while (*p++ != '\n');
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: pad_output
X *
X * FUNCTION: Writes tabs and spaces to move the current column up to the desired
X * position.
X *
X * ALGORITHM: Put tabs and/or blanks into pobuf, then write pobuf.
X *
X * PARAMETERS: current integer The current column target
X * nteger The desired column
X *
X * RETURNS: Integer value of the new column. (If current >= target, no action is
X * taken, and current is returned.
X *
X * GLOBALS: None
X *
X * CALLS: write (sys)
X *
X * CALLED BY: dump_line
X *
X * HISTORY: initial coding November 1976 D A Willcox of CAC
X *
X */
Xpad_output(current, target) /* writes tabs and blanks (if necessary) to
X * get the current output position up to the
X * target column */
X int current; /* the current column value */
X int target; /* position we want it at */
X{
X register int curr; /* internal column pointer */
X register int tcur;
X
X if (troff)
X fprintf(output, "\\h'|%dp'", (target - 1) * 7);
X else {
X if (current >= target)
X return (current); /* line is already long enough */
X curr = current;
X while ((tcur = ((curr - 1) & tabmask) + tabsize + 1) <= target) {
X putc('\t', output);
X curr = tcur;
X }
X while (curr++ < target)
X putc(' ', output); /* pad with final blanks */
X }
X return (target);
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: count_spaces
X *
X * FUNCTION: Find out where printing of a given string will leave the current
X * character position on output.
X *
X * ALGORITHM: Run thru input string and add appropriate values to current
X * position.
X *
X * RETURNS: Integer value of position after printing "buffer" starting in column
X * "current".
X *
X * HISTORY: initial coding November 1976 D A Willcox of CAC
X *
X */
Xint
Xcount_spaces(current, buffer)
X/*
X * this routine figures out where the character position will be after
X * printing the text in buffer starting at column "current"
X */
X int current;
X char *buffer;
X{
X register char *buf; /* used to look thru buffer */
X register int cur; /* current character counter */
X
X cur = current;
X
X for (buf = buffer; *buf != '\0'; ++buf) {
X switch (*buf) {
X
X case '\n':
X case 014: /* form feed */
X cur = 1;
X break;
X
X case '\t':
X cur = ((cur - 1) & tabmask) + tabsize + 1;
X break;
X
X case '\b': /* this is a backspace */
X --cur;
X break;
X
X default:
X ++cur;
X break;
X } /* end of switch */
X } /* end of for loop */
X return (cur);
X};
X
Xint found_err;
Xdiag(level, msg, a, b)
X{
X if (level)
X found_err = 1;
X if (output == stdout) {
X fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no);
X fprintf(stdout, msg, a, b);
X fprintf(stdout, " */\n");
X }
X else {
X fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no);
X fprintf(stderr, msg, a, b);
X fprintf(stderr, "\n");
X }
X}
X
Xwritefdef(f, nm)
X register struct fstate *f;
X{
X fprintf(output, ".ds f%c %s\n.nr s%c %d\n",
X nm, f->font, nm, f->size);
X}
X
Xchar *
Xchfont(of, nf, s)
X register struct fstate *of,
X *nf;
X char *s;
X{
X if (of->font[0] != nf->font[0]
X || of->font[1] != nf->font[1]) {
X *s++ = '\\';
X *s++ = 'f';
X if (nf->font[1]) {
X *s++ = '(';
X *s++ = nf->font[0];
X *s++ = nf->font[1];
X }
X else
X *s++ = nf->font[0];
X }
X if (nf->size != of->size) {
X *s++ = '\\';
X *s++ = 's';
X if (nf->size < of->size) {
X *s++ = '-';
X *s++ = '0' + of->size - nf->size;
X }
X else {
X *s++ = '+';
X *s++ = '0' + nf->size - of->size;
X }
X }
X return s;
X}
X
X
Xparsefont(f, s0)
X register struct fstate *f;
X char *s0;
X{
X register char *s = s0;
X int sizedelta = 0;
X bzero(f, sizeof *f);
X while (*s) {
X if (isdigit(*s))
X f->size = f->size * 10 + *s - '0';
X else if (isupper(*s))
X if (f->font[0])
X f->font[1] = *s;
X else
X f->font[0] = *s;
X else if (*s == 'c')
X f->allcaps = 1;
X else if (*s == '+')
X sizedelta++;
X else if (*s == '-')
X sizedelta--;
X else {
X fprintf(stderr, "indent: bad font specification: %s\n", s0);
X exit(1);
X }
X s++;
X }
X if (f->font[0] == 0)
X f->font[0] = 'R';
X if (bodyf.size == 0)
X bodyf.size = 11;
X if (f->size == 0)
X f->size = bodyf.size + sizedelta;
X else if (sizedelta > 0)
X f->size += bodyf.size;
X else
X f->size = bodyf.size - f->size;
X}
END_OF_FILE
if test 15511 -ne `wc -c <'indent/io.c'`; then
echo shar: \"'indent/io.c'\" unpacked with wrong size!
fi
# end of 'indent/io.c'
fi
if test -f 'indent/lexi.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'indent/lexi.c'\"
else
echo shar: Extracting \"'indent/lexi.c'\" \(15857 characters\)
sed "s/^X//" >'indent/lexi.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[] = "@(#)lexi.c 5.11 (Berkeley) 9/15/88";
X#endif /* not lint */
X
X/*
X * Here we have the token scanner for indent. It scans off one token and puts
X * it in the global variable "token". It returns a code, indicating the type
X * of token scanned.
X */
X
X#include "indent_globs.h"
X#include "indent_codes.h"
X#include "ctype.h"
X
Xtypedef enum char_type {
X alphanum = 1,
X opchar = 3,
X colonchar = 4
X} char_type;
X
Xstruct templ {
X char *rwd;
X int rwcode;
X cplus_flag cplus;
X};
X
Xstruct templ specials[100] =
X{
X "switch", 1, c_and_cplus,
X "case", 2, c_and_cplus,
X "break", 0, c_and_cplus,
X "struct", 3, c_and_cplus,
X "union", 3, c_and_cplus,
X "enum", 3, c_and_cplus,
X "default", 2, c_and_cplus,
X "int", 4, c_and_cplus,
X "char", 4, c_and_cplus,
X "float", 4, c_and_cplus,
X "double", 4, c_and_cplus,
X "long", 4, c_and_cplus,
X "short", 4, c_and_cplus,
X "typedef", 8, c_and_cplus,
X "unsigned", 4, c_and_cplus,
X "register", 4, c_and_cplus,
X "static", 4, c_and_cplus,
X "global", 4, c_and_cplus,
X "extern", 4, c_and_cplus,
X "void", 4, c_and_cplus,
X "goto", 0, c_and_cplus,
X "return", 0, c_and_cplus,
X "if", 5, c_and_cplus,
X "while", 5, c_and_cplus,
X "for", 5, c_and_cplus,
X "else", 6, c_and_cplus,
X "do", 6, c_and_cplus,
X "sizeof", 7, c_and_cplus,
X "class", 3, cplus_only,
X "public", 2, cplus_only,
X "private", 2, cplus_only,
X "protected", 2, cplus_only,
X "volatile", 4, c_and_cplus,
X
X 0, 0
X};
X
Xchar chartype[128] =
X{ /* this is used to facilitate the decision of
X * what type (alphanumeric, operator) each
X * character is */
X 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 3, 0, 0, 1, 3, 3, 0,
X 0, 0, 3, 3, 0, 3, 0, 3,
X 1, 1, 1, 1, 1, 1, 1, 1,
X 1, 1, 4, 0, 3, 3, 3, 3,
X 0, 1, 1, 1, 1, 1, 1, 1,
X 1, 1, 1, 1, 1, 1, 1, 1,
X 1, 1, 1, 1, 1, 1, 1, 1,
X 1, 1, 1, 0, 0, 0, 3, 1,
X 0, 1, 1, 1, 1, 1, 1, 1,
X 1, 1, 1, 1, 1, 1, 1, 1,
X 1, 1, 1, 1, 1, 1, 1, 1,
X 1, 1, 1, 0, 3, 0, 3, 0
X};
X
X
X
X
Xint
Xlexi()
X{
X register char *tok; /* local pointer to next char in token */
X int unary_delim; /* this is set to 1 if the current token
X *
X * forces a following operator to be unary */
X static int last_code; /* the last token type returned */
X static int l_struct; /* set to 1 if the last token was 'struct' */
X static int l_struct_start; /* set at struct, cleared at { or ; */
X static int l_class; /* in c++, class name coming next. */
X int code; /* internal code to be returned */
X char qchar; /* the delimiter character for a string */
X
X tok = token; /* point to start of place to save token */
X unary_delim = false;
X ps.col_1 = ps.last_nl; /* tell world that this token started in
X * column 1 iff the last thing scanned was nl */
X ps.last_nl = false;
X
X while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */
X ps.col_1 = false; /* leading blanks imply token is not in column
X * 1 */
X if (++buf_ptr >= buf_end)
X fill_buffer();
X }
X
X /* Scan an alphanumeric token */
X /* In c++, :: starting token is aok, as is ~ sometimes */
X /* well, int x = ~y; will work oddly here */
X if (((char_type)chartype[*buf_ptr] == alphanum || buf_ptr[0] == '.' && isdigit(buf_ptr[1])) ||
X (cplus && buf_ptr[0] == ':' && buf_ptr[1] == ':') ||
X (cplus && ps.in_decl && *buf_ptr == '~'
X && (char_type)chartype[buf_ptr[1]] == alphanum) /* destructors in classdefs */
X ) {
X /*
X * we have a character or number
X */
X register char *j; /* used for searching thru list of
X *
X * reserved words */
X register struct templ *p;
X
X if (isdigit(*buf_ptr) || buf_ptr[0] == '.' && isdigit(buf_ptr[1])) {
X int seendot = 0,
X seenexp = 0;
X if (*buf_ptr == '0' &&
X (buf_ptr[1] == 'x' || buf_ptr[1] == 'X')) {
X *tok++ = *buf_ptr++;
X *tok++ = *buf_ptr++;
X while (isxdigit(*buf_ptr))
X *tok++ = *buf_ptr++;
X }
X else
X while (1) {
X if (*buf_ptr == '.')
X if (seendot)
X break;
X else
X seendot++;
X *tok++ = *buf_ptr++;
X if (!isdigit(*buf_ptr) && *buf_ptr != '.')
X if ((*buf_ptr != 'E' && *buf_ptr != 'e') || seenexp)
X break;
X else {
X seenexp++;
X seendot++;
X *tok++ = *buf_ptr++;
X if (*buf_ptr == '+' || *buf_ptr == '-')
X *tok++ = *buf_ptr++;
X }
X }
X if (*buf_ptr == 'L' || *buf_ptr == 'l')
X *tok++ = *buf_ptr++;
X }
X else {
X int first;
X first = 1;
X while ((char_type)chartype[*buf_ptr] == alphanum ||
X (buf_ptr[0] == ':' && buf_ptr[1] == ':' && cplus) ||
X (cplus && first && buf_ptr[0] == '~'))
X { /* copy it over */
X int colonp;
X first = 0;
X colonp = *buf_ptr == ':';
X *tok++ = *buf_ptr++;
X if(colonp) {
X *tok++ = *buf_ptr++;
X /* foo::~foo */
X if(*buf_ptr == '~') *tok++ = *buf_ptr++;
X colonp = 0;
X }
X if (buf_ptr >= buf_end)
X fill_buffer();
X }
X }
X *tok++ = '\0';
X while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */
X if (++buf_ptr >= buf_end)
X fill_buffer();
X }
X ps.its_a_keyword = false;
X ps.sizeof_keyword = false;
X if (l_struct) { /* if last token was 'struct', then this token
X * should be treated as a declaration */
X if(l_class) addkey(tok, 4);
X l_class = false;
X l_struct = false;
X last_code = ident;
X ps.last_u_d = true;
X return (decl);
X }
X ps.last_u_d = false; /* Operator after indentifier is binary */
X last_code = ident; /* Remember that this is the code we will
X * return */
X
X /*
X * This loop will check if the token is a keyword.
X */
X for (p = specials; (j = p->rwd) != 0; p++) {
X tok = token; /* point at scanned token */
X if (*j++ != *tok++ || *j++ != *tok++)
X continue; /* This test depends on the fact that
X * identifiers are always at least 1 character
X * long (ie. the first two bytes of the
X * identifier are always meaningful) */
X if (tok[-1] == 0)
X break; /* If its a one-character identifier */
X while (*tok++ == *j)
X if (*j++ == 0 &&
X (p->cplus == c_and_cplus ||
X (cplus && p->cplus == cplus_only) ||
X (!cplus && p->cplus == c_only)))
X goto found_keyword; /* I wish that C had a multi-level
X * break... */
X }
X if (p->rwd) { /* we have a keyword */
X found_keyword:
X ps.its_a_keyword = true;
X ps.last_u_d = true;
X switch (p->rwcode) {
X case 1: /* it is a switch */
X return (swstmt);
X case 2: /* a case or default */
X return (casestmt);
X
X case 3: /* a "struct" */
X if (ps.p_l_follow)
X break; /* inside parens: cast */
X l_struct = true;
X if(cplus)l_struct_start = true;
X /* automatically note keywords */
X if(cplus && strcmp(tok, "class") == 0 ||
X strcmp(tok, "struct") == 0 ||
X strcmp(tok, "union") == 0 ||
X strcmp(tok, "enum") == 0)
X l_class = true;
X /*
X * Next time around, we will want to know that we have had a
X * 'struct'
X */
X case 4: /* one of the declaration keywords */
X if (ps.p_l_follow) {
X ps.cast_mask |= 1 << ps.p_l_follow;
X break; /* inside parens: cast */
X }
X last_code = decl;
X return (decl);
X
X case 5: /* if, while, for */
X return (sp_paren);
X
X case 6: /* do, else */
X return (sp_nparen);
X
X case 7:
X ps.sizeof_keyword = true;
X return (ident);
X
X case 8: /* typedef is a decl */
X last_code = decl;
X return (decl);
X
X default: /* all others are treated like any other
X * identifier */
X return (ident);
X } /* end of switch */
X } /* end of if (found_it) */
X if (*buf_ptr == '(' && ps.tos <= 1 && ps.ind_level == 0) {
X register char *tp = buf_ptr;
X while (tp < buf_end)
X if (*tp++ == ')' && *tp == ';')
X goto not_proc;
X strncpy(ps.procname, token, sizeof ps.procname - 1);
X ps.in_parameter_declaration = 1;
X not_proc:;
X }
X /*
X * The following hack attempts to guess whether or not the current
X * token is in fact a declaration keyword -- one that has been
X * typedefd
X */
X if (((*buf_ptr == '*' && buf_ptr[1] != '=') || isalpha(*buf_ptr) || *buf_ptr == '_')
X && !ps.p_l_follow
X && !ps.block_init
X && (ps.last_token == rparen || ps.last_token == semicolon ||
X ps.last_token == decl ||
X ps.last_token == lbrace || ps.last_token == rbrace)) {
X ps.its_a_keyword = true;
X ps.last_u_d = true;
X last_code = decl;
X return decl;
X }
X if (last_code == decl) /* if this is a declared variable, then
X * following sign is unary */
X ps.last_u_d = true; /* will make "int a -1" work */
X last_code = ident;
X return (ident); /* the ident is not in the list */
X } /* end of procesing for alpanum character */
X /* l l l Scan a non-alphanumeric token */
X
X l_class = false; /* struct { ain't defining a class. */
X *tok++ = *buf_ptr; /* if it is only a one-character token, it is
X * moved here */
X *tok = '\0';
X if (++buf_ptr >= buf_end)
X fill_buffer();
X
X switch (*token) {
X case '\n':
X unary_delim = ps.last_u_d;
X ps.last_nl = true; /* remember that we just had a newline */
X code = (had_eof ? 0 : newline);
X
X /*
X * if data has been exausted, the newline is a dummy, and we should
X * return code to stop
X */
X break;
X
X case '\'': /* start of quoted character */
X case '"': /* start of string */
X qchar = *token;
X if (troff) {
X tok[-1] = '`';
X if (qchar == '"')
X *tok++ = '`';
X tok = chfont(&bodyf, &stringf, tok);
X }
X do { /* copy the string */
X while (1) { /* move one character or [/<char>]<char> */
X if (*buf_ptr == '\n') {
X printf("%d: Unterminated literal\n", line_no);
X goto stop_lit;
X }
X *tok = *buf_ptr++;
X if (buf_ptr >= buf_end)
X fill_buffer();
X if (had_eof || ((tok - token) > (bufsize - 2))) {
X printf("Unterminated literal\n");
X ++tok;
X goto stop_lit;
X /* get outof literal copying loop */
X }
X if (*tok == BACKSLASH) { /* if escape, copy extra char */
X if (*buf_ptr == '\n') /* check for escaped newline */
X ++line_no;
X if (troff) {
X *++tok = BACKSLASH;
X if (*buf_ptr == BACKSLASH)
X *++tok = BACKSLASH;
X }
X *++tok = *buf_ptr++;
X ++tok; /* we must increment this again because we
X * copied two chars */
X if (buf_ptr >= buf_end)
X fill_buffer();
X }
X else
X break; /* we copied one character */
X } /* end of while (1) */
X } while (*tok++ != qchar);
X if (troff) {
X tok = chfont(&stringf, &bodyf, tok - 1);
X if (qchar == '"')
X *tok++ = '\'';
X }
Xstop_lit:
X code = ident;
X break;
X
X case ('('):
X case ('['):
X unary_delim = true;
X code = lparen;
X break;
X
X case (')'):
X case (']'):
X code = rparen;
X break;
X
X case '#':
X unary_delim = ps.last_u_d;
X code = preesc;
X break;
X
X case '?':
X unary_delim = true;
X code = question;
X break;
X
X case (':'):
X if(l_struct_start)
X code = ident;
X else code = colon;
X unary_delim = true;
X break;
X
X case (';'):
X l_struct_start = false;
X unary_delim = true;
X code = semicolon;
X break;
X
X case ('{'):
X l_struct_start = false;
X unary_delim = true;
X
X /*
X * if (ps.in_or_st) ps.block_init = 1;
X */
X /* ? code = ps.block_init ? lparen : lbrace; */
X code = lbrace;
X break;
X
X case ('}'):
X unary_delim = true;
X /* ? code = ps.block_init ? rparen : rbrace; */
X code = rbrace;
X break;
X
X case 014: /* a form feed */
X unary_delim = ps.last_u_d;
X ps.last_nl = true; /* remember this so we can set 'ps.col_1'
X * right */
X code = form_feed;
X break;
X
X case (','):
X unary_delim = true;
X code = comma;
X break;
X
X case '.':
X unary_delim = false;
X code = period;
X break;
X
X case '-':
X case '+': /* check for -, +, --, ++ */
X code = (ps.last_u_d ? unary_op : binary_op);
X unary_delim = true;
X
X if (*buf_ptr == token[0]) {
X /* check for doubled character */
X *tok++ = *buf_ptr++;
X /* buffer overflow will be checked at end of loop */
X if (last_code == ident || last_code == rparen) {
X code = (ps.last_u_d ? unary_op : postop);
X /* check for following ++ or -- */
X unary_delim = false;
X }
X }
X else if (*buf_ptr == '=')
X /* check for operator += */
X *tok++ = *buf_ptr++;
X else if (*buf_ptr == '>') {
X /* check for operator -> */
X *tok++ = *buf_ptr++;
X if (!pointer_as_binop) {
X unary_delim = false;
X code = unary_op;
X ps.want_blank = false;
X }
X }
X break; /* buffer overflow will be checked at end of
X * switch */
X
X case '=':
X if (ps.in_or_st)
X ps.block_init = 1;
X#ifdef undef
X if (chartype[*buf_ptr] == opchar) { /* we have two char assignment */
X tok[-1] = *buf_ptr++;
X if ((tok[-1] == '<' || tok[-1] == '>') && tok[-1] == *buf_ptr)
X *tok++ = *buf_ptr++;
X *tok++ = '='; /* Flip =+ to += */
X *tok = 0;
X }
X#else
X if (*buf_ptr == '=') {/* == */
X *tok++ = '='; /* Flip =+ to += */
X buf_ptr++;
X *tok = 0;
X }
X#endif
X code = binary_op;
X unary_delim = true;
X break;
X /* can drop thru!!! */
X
X case '>':
X case '<':
X case '!': /* ops like <, <<, <=, !=, etc */
X if (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=') {
X *tok++ = *buf_ptr;
X if (++buf_ptr >= buf_end)
X fill_buffer();
X }
X if (*buf_ptr == '=')
X *tok++ = *buf_ptr++;
X code = (ps.last_u_d ? unary_op : binary_op);
X unary_delim = true;
X break;
X
X default:
X if (token[0] == '/' && *buf_ptr == '*') {
X /* it is start of a C comment */
X *tok++ = '*';
X
X if (++buf_ptr >= buf_end)
X fill_buffer();
X
X code = comment;
X unary_delim = ps.last_u_d;
X break;
X }
X if (token[0] == '/' && *buf_ptr == '/') {
X /* it is start of a C++ comment */
X *tok++ = '/';
X
X if (++buf_ptr >= buf_end)
X fill_buffer();
X
X code = cc_commnt;
X ps.cc_comment++;
X unary_delim = ps.last_u_d;
X break;
X }
X while (*(tok - 1) == *buf_ptr || *buf_ptr == '=') {
X /*
X * handle ||, &&, etc, and also things as in int *****i
X */
X *tok++ = *buf_ptr;
X if (++buf_ptr >= buf_end)
X fill_buffer();
X }
X code = (ps.last_u_d ? unary_op : binary_op);
X unary_delim = true;
X
X
X } /* end of switch */
X if (code != newline) {
X l_struct = false;
X last_code = code;
X }
X if (buf_ptr >= buf_end) /* check for input buffer empty */
X fill_buffer();
X ps.last_u_d = unary_delim;
X *tok = '\0'; /* null terminate the token */
X return (code);
X};
X
X/*
X * Add the given keyword to the keyword table, using val as the keyword type
X */
Xaddkey(key, val)
X char *key;
X{
X register struct templ *p = specials;
X while (p->rwd)
X if (p->rwd[0] == key[0] && strcmp(p->rwd, key) == 0)
X return;
X else
X p++;
X if (p >= specials + sizeof specials / sizeof specials[0])
X return; /* For now, table overflows are silently
X * ignored */
X p->rwd = key;
X p->rwcode = val;
X p[1].rwd = 0;
X p[1].rwcode = 0;
X return;
X}
END_OF_FILE
if test 15857 -ne `wc -c <'indent/lexi.c'`; then
echo shar: \"'indent/lexi.c'\" unpacked with wrong size!
fi
# end of 'indent/lexi.c'
fi
echo shar: End of archive 2 \(of 3\).
cp /dev/null ark2isdone
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.