home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
unix
/
volume18
/
indent
/
part02
< prev
next >
Wrap
Text File
|
1989-03-20
|
44KB
|
1,595 lines
Subject: v18i050: Indent, C reformatting program, Part02/03
Newsgroups: comp.sources.unix
Sender: sources
Approved: rsalz@uunet.UU.NET
Submitted-by: Ozan Yigit <oz@nexus.yorku.ca>
Posting-number: Volume 18, Issue 50
Archive-name: indent/part02
#! /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 2 (of 3)."
# Contents: indent/io.c indent/lexi.c indent/pr_comment.c
# Wrapped by oz@yunexus on Thu Mar 9 18:11:05 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
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'\" \(14572 characters\)
sed "s/^X//" >'indent/io.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[] = "@(#)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 ps.ind_stmt = 0; /* this is a class A kludge. dont do
X * additional statement indentation if we are
X * at bracket level 0 */
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 (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] == '*')
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) {
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 ? (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 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 }
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 '': /* 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
echo shar: 1 control character may be missing from \"'indent/io.c'\"
if test 14572 -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'\" \(13568 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
X#define alphanum 1
X#define opchar 3
X
Xstruct templ {
X char *rwd;
X int rwcode;
X};
X
Xstruct templ specials[100] =
X{
X "switch", 1,
X "case", 2,
X "break", 0,
X "struct", 3,
X "union", 3,
X "enum", 3,
X "default", 2,
X "int", 4,
X "char", 4,
X "float", 4,
X "double", 4,
X "long", 4,
X "short", 4,
X "typdef", 4,
X "unsigned", 4,
X "register", 4,
X "static", 4,
X "global", 4,
X "extern", 4,
X "void", 4,
X "goto", 0,
X "return", 0,
X "if", 5,
X "while", 5,
X "for", 5,
X "else", 6,
X "do", 6,
X "sizeof", 7,
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, 0, 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 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 if (chartype[*buf_ptr] == alphanum || buf_ptr[0] == '.' && isdigit(buf_ptr[1])) {
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 while (chartype[*buf_ptr] == alphanum) { /* copy it over */
X *tok++ = *buf_ptr++;
X if (buf_ptr >= buf_end)
X fill_buffer();
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 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 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
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 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 *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 code = colon;
X unary_delim = true;
X break;
X
X case (';'):
X unary_delim = true;
X code = semicolon;
X break;
X
X case ('{'):
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 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 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 13568 -ne `wc -c <'indent/lexi.c'`; then
echo shar: \"'indent/lexi.c'\" unpacked with wrong size!
fi
# end of 'indent/lexi.c'
fi
if test -f 'indent/pr_comment.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'indent/pr_comment.c'\"
else
echo shar: Extracting \"'indent/pr_comment.c'\" \(11737 characters\)
sed "s/^X//" >'indent/pr_comment.c' <<'END_OF_FILE'
X/*
X * Copyright (c) 1985 Sun Microsystems, Inc.
X * Copyright (c) 1980 The Regents of the University of California.
X * Copyright (c) 1976 Board of Trustees of the University of Illinois.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley, the University of Illinois,
X * Urbana, and Sun Microsystems, Inc. The name of either University
X * or Sun Microsystems may not be used to endorse or promote products
X * derived from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)pr_comment.c 5.9 (Berkeley) 9/15/88";
X#endif /* not lint */
X
X/*
X * NAME:
X * pr_comment
X *
X * FUNCTION:
X * This routine takes care of scanning and printing comments.
X *
X * ALGORITHM:
X * 1) Decide where the comment should be aligned, and if lines should
X * be broken.
X * 2) If lines should not be broken and filled, just copy up to end of
X * comment.
X * 3) If lines should be filled, then scan thru input_buffer copying
X * characters to com_buf. Remember where the last blank, tab, or
X * newline was. When line is filled, print up to last blank and
X * continue copying.
X *
X * HISTORY:
X * November 1976 D A Willcox of CAC Initial coding
X * 12/6/76 D A Willcox of CAC Modification to handle
X * UNIX-style comments
X *
X */
X
X/*
X * this routine processes comments. It makes an attempt to keep comments from
X * going over the max line length. If a line is too long, it moves everything
X * from the last blank to the next comment line. Blanks and tabs from the
X * beginning of the input line are removed
X */
X
X
X#include "indent_globs.h"
X
X
Xpr_comment()
X{
X int now_col; /* column we are in now */
X int adj_max_col; /* Adjusted max_col for when we decide to
X * spill comments over the right margin */
X char *last_bl; /* points to the last blank in the output
X * buffer */
X char *t_ptr; /* used for moving string */
X int unix_comment; /* tri-state variable used to decide if it is
X * a unix-style comment. 0 means only blanks
X * since /*, 1 means regular style comment, 2
X * means unix style comment */
X int break_delim = comment_delimiter_on_blankline;
X int l_just_saw_decl = ps.just_saw_decl;
X /*
X * int ps.last_nl = 0; /* true iff the last significant thing
X * weve seen is a newline
X */
X int one_liner = 1; /* true iff this comment is a one-liner */
X adj_max_col = max_col;
X ps.just_saw_decl = 0;
X last_bl = 0; /* no blanks found so far */
X ps.box_com = false; /* at first, assume that we are not in
X * a boxed comment or some other
X * comment that should not be touched */
X ++ps.out_coms; /* keep track of number of comments */
X unix_comment = 1; /* set flag to let us figure out if there is a
X * unix-style comment ** DISABLED: use 0 to
X * reenable this hack! */
X
X /* Figure where to align and how to treat the comment */
X
X if (ps.col_1 && !format_col1_comments) { /* if comment starts in column
X * 1 it should not be touched */
X ps.box_com = true;
X ps.com_col = 1;
X }
X else {
X if (*buf_ptr == '-' || *buf_ptr == '*') {
X ps.box_com = true; /* a comment with a '-' or '*' immediately
X * after the /* is assumed to be a boxed
X * comment */
X break_delim = 0;
X }
X if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) {
X /* klg: check only if this line is blank */
X /*
X * If this (*and previous lines are*) blank, dont put comment way
X * out at left
X */
X ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
X adj_max_col = block_comment_max_col;
X if (ps.com_col <= 1)
X ps.com_col = 1 + !format_col1_comments;
X }
X else {
X register target_col;
X break_delim = 0;
X if (s_code != e_code)
X target_col = count_spaces(compute_code_target(), s_code);
X else {
X target_col = 1;
X if (s_lab != e_lab)
X target_col = count_spaces(compute_label_target(), s_lab);
X }
X ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? ps.decl_com_ind : ps.com_ind;
X if (ps.com_col < target_col)
X ps.com_col = ((target_col + 7) & ~7) + 1;
X if (ps.com_col + 24 > adj_max_col)
X adj_max_col = ps.com_col + 24;
X }
X }
X if (ps.box_com) {
X buf_ptr[-2] = 0;
X ps.n_comment_delta = 1 - count_spaces(1, in_buffer);
X buf_ptr[-2] = '/';
X }
X else {
X ps.n_comment_delta = 0;
X while (*buf_ptr == ' ' || *buf_ptr == '\t')
X buf_ptr++;
X }
X ps.comment_delta = 0;
X *e_com++ = '/'; /* put '/*' into buffer */
X *e_com++ = '*';
X if (*buf_ptr != ' ' && !ps.box_com)
X *e_com++ = ' ';
X
X *e_com = '\0';
X if (troff) {
X now_col = 1;
X adj_max_col = 80;
X }
X else
X now_col = count_spaces(ps.com_col, s_com); /* figure what column we
X * would be in if we
X * printed the comment
X * now */
X
X /* Start to copy the comment */
X
X while (1) { /* this loop will go until the comment is
X * copied */
X if (*buf_ptr > 040 && *buf_ptr != '*')
X ps.last_nl = 0;
X check_size(com);
X switch (*buf_ptr) { /* this checks for various spcl cases */
X case 014: /* check for a form feed */
X if (!ps.box_com) { /* in a text comment, break the line here */
X ps.use_ff = true;
X /* fix so dump_line uses a form feed */
X dump_line();
X last_bl = 0;
X *e_com++ = ' ';
X *e_com++ = '*';
X *e_com++ = ' ';
X while (*++buf_ptr == ' ' || *buf_ptr == '\t');
X }
X else {
X if (++buf_ptr >= buf_end)
X fill_buffer();
X *e_com++ = 014;
X }
X break;
X
X case '\n':
X if (had_eof) { /* check for unexpected eof */
X printf("Unterminated comment\n");
X *e_com = '\0';
X dump_line();
X return;
X }
X one_liner = 0;
X if (ps.box_com || ps.last_nl) { /* if this is a boxed comment,
X * we dont ignore the newline */
X if (s_com == e_com) {
X *e_com++ = ' ';
X *e_com++ = ' ';
X }
X *e_com = '\0';
X if (!ps.box_com && e_com - s_com > 3) {
X if (break_delim == 1 && s_com[0] == '/'
X && s_com[1] == '*' && s_com[2] == ' ') {
X char *t = e_com;
X break_delim = 2;
X e_com = s_com + 2;
X *e_com = 0;
X if (blanklines_before_blockcomments)
X prefix_blankline_requested = 1;
X dump_line();
X e_com = t;
X s_com[0] = s_com[1] = s_com[2] = ' ';
X }
X dump_line();
X check_size(com);
X *e_com++ = ' ';
X *e_com++ = ' ';
X }
X dump_line();
X now_col = ps.com_col;
X }
X else {
X ps.last_nl = 1;
X if (unix_comment != 1) { /* we not are in unix_style
X * comment */
X if (unix_comment == 0 && s_code == e_code) {
X /*
X * if it is a UNIX-style comment, ignore the
X * requirement that previous line be blank for
X * unindention
X */
X ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
X if (ps.com_col <= 1)
X ps.com_col = 2;
X }
X unix_comment = 2; /* permanently remember that we are in
X * this type of comment */
X dump_line();
X ++line_no;
X now_col = ps.com_col;
X *e_com++ = ' ';
X /*
X * fix so that the star at the start of the line will line
X * up
X */
X do /* flush leading white space */
X if (++buf_ptr >= buf_end)
X fill_buffer();
X while (*buf_ptr == ' ' || *buf_ptr == '\t');
X break;
X }
X if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t')
X last_bl = e_com - 1;
X /*
X * if there was a space at the end of the last line, remember
X * where it was
X */
X else { /* otherwise, insert one */
X last_bl = e_com;
X check_size(com);
X *e_com++ = ' ';
X ++now_col;
X }
X }
X ++line_no; /* keep track of input line number */
X if (!ps.box_com) {
X int nstar = 1;
X do { /* flush any blanks and/or tabs at start of
X * next line */
X if (++buf_ptr >= buf_end)
X fill_buffer();
X if (*buf_ptr == '*' && --nstar >= 0) {
X if (++buf_ptr >= buf_end)
X fill_buffer();
X if (*buf_ptr == '/')
X goto end_of_comment;
X }
X } while (*buf_ptr == ' ' || *buf_ptr == '\t');
X }
X else if (++buf_ptr >= buf_end)
X fill_buffer();
X break; /* end of case for newline */
X
X case '*': /* must check for possibility of being at end
X * of comment */
X if (++buf_ptr >= buf_end) /* get to next char after * */
X fill_buffer();
X
X if (unix_comment == 0) /* set flag to show we are not in
X * unix-style comment */
X unix_comment = 1;
X
X if (*buf_ptr == '/') { /* it is the end!!! */
X end_of_comment:
X if (++buf_ptr >= buf_end)
X fill_buffer();
X
X if (*(e_com - 1) != ' ' && !ps.box_com) { /* insure blank before
X * end */
X *e_com++ = ' ';
X ++now_col;
X }
X if (break_delim == 1 && !one_liner && s_com[0] == '/'
X && s_com[1] == '*' && s_com[2] == ' ') {
X char *t = e_com;
X break_delim = 2;
X e_com = s_com + 2;
X *e_com = 0;
X if (blanklines_before_blockcomments)
X prefix_blankline_requested = 1;
X dump_line();
X e_com = t;
X s_com[0] = s_com[1] = s_com[2] = ' ';
X }
X if (break_delim == 2 && e_com > s_com + 3
X /* now_col > adj_max_col - 2 && !ps.box_com */ ) {
X *e_com = '\0';
X dump_line();
X now_col = ps.com_col;
X }
X check_size(com);
X *e_com++ = '*';
X *e_com++ = '/';
X *e_com = '\0';
X ps.just_saw_decl = l_just_saw_decl;
X return;
X }
X else { /* handle isolated '*' */
X *e_com++ = '*';
X ++now_col;
X }
X break;
X default: /* we have a random char */
X if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t')
X unix_comment = 1; /* we are not in unix-style comment */
X
X *e_com = *buf_ptr++;
X if (buf_ptr >= buf_end)
X fill_buffer();
X
X if (*e_com == '\t') /* keep track of column */
X now_col = ((now_col - 1) & tabmask) + tabsize + 1;
X else if (*e_com == '\b') /* this is a backspace */
X --now_col;
X else
X ++now_col;
X
X if (*e_com == ' ' || *e_com == '\t')
X last_bl = e_com;
X /* remember we saw a blank */
X
X ++e_com;
X if (now_col > adj_max_col && !ps.box_com && unix_comment == 1 && e_com[-1] > ' ') {
X /*
X * the comment is too long, it must be broken up
X */
X if (break_delim == 1 && s_com[0] == '/'
X && s_com[1] == '*' && s_com[2] == ' ') {
X char *t = e_com;
X break_delim = 2;
X e_com = s_com + 2;
X *e_com = 0;
X if (blanklines_before_blockcomments)
X prefix_blankline_requested = 1;
X dump_line();
X e_com = t;
X s_com[0] = s_com[1] = s_com[2] = ' ';
X }
X if (last_bl == 0) { /* we have seen no blanks */
X last_bl = e_com; /* fake it */
X *e_com++ = ' ';
X }
X *e_com = '\0'; /* print what we have */
X *last_bl = '\0';
X while (last_bl > s_com && last_bl[-1] < 040)
X *--last_bl = 0;
X e_com = last_bl;
X dump_line();
X
X *e_com++ = ' '; /* add blanks for continuation */
X *e_com++ = ' ';
X *e_com++ = ' ';
X
X t_ptr = last_bl + 1;
X last_bl = 0;
X if (t_ptr >= e_com) {
X while (*t_ptr == ' ' || *t_ptr == '\t')
X t_ptr++;
X while (*t_ptr != '\0') { /* move unprinted part of
X * comment down in buffer */
X if (*t_ptr == ' ' || *t_ptr == '\t')
X last_bl = e_com;
X *e_com++ = *t_ptr++;
X }
X }
X *e_com = '\0';
X now_col = count_spaces(ps.com_col, s_com); /* recompute current
X * position */
X }
X break;
X }
X }
X}
END_OF_FILE
if test 11737 -ne `wc -c <'indent/pr_comment.c'`; then
echo shar: \"'indent/pr_comment.c'\" unpacked with wrong size!
fi
# end of 'indent/pr_comment.c'
fi
echo shar: End of archive 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 need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0