Replace indent with NetBSD version

- minix-port.patch is empty as it compiles unchanged
This commit is contained in:
Vivek Prakash 2011-07-02 23:26:53 +00:00 committed by Ben Gras
parent 4e37b49261
commit 97c7d358ea
26 changed files with 5011 additions and 4042 deletions

View file

@ -13,7 +13,7 @@ SUBDIR= aal add_route adduser advent arp ash at autil awk \
ed eject elle elvis env expand factor file \
find finger fingerd fix fold format fortune fsck.mfs \
ftp101 ftpd200 gcov-pull getty grep gomoku head hexdump host \
hostaddr id ifconfig ifdef indent install \
hostaddr id ifconfig ifdef install \
intr ipcrm ipcs irdpd isoread join kill last leave \
less lex life loadkeys loadramdisk logger login look lp \
lpd ls lspci M mail make MAKEDEV man \

View file

@ -1,7 +0,0 @@
# Makefile for indent
PROG= indent
SRCS= args.c comment.c lexi.c indent.c parse.c io.c
MAN=
.include <bsd.prog.mk>

View file

@ -1,287 +0,0 @@
/**
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980 The Regents of the University of California.
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley, the University of Illinois,
* Urbana, and Sun Microsystems, Inc. The name of either University
* or Sun Microsystems may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
* Argument scanning and profile reading code. Default parameters are set
* here as well.
*/
#define PUBLIC extern
#include <sys/types.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "globs.h"
#include "proto.h"
/* profile types */
#define PRO_SPECIAL 1 /* special case */
#define PRO_BOOL 2 /* boolean */
#define PRO_INT 3 /* integer */
#define PRO_FONT 4 /* troff font */
/* profile specials for booleans */
#define ON 1 /* turn it on */
#define OFF 0 /* turn it off */
/* profile specials for specials */
#define IGN 1 /* ignore it */
#define CLI 2 /* case label indent (float) */
#define STDIN 3 /* use stdin */
#define KEY 4 /* type (keyword) */
/*
* N.B.: because of the way the table here is scanned, options whose names
* are substrings of other options must occur later; that is, with -lp vs -l,
* -lp must be first. Also, while (most) booleans occur more than once, the
* last default value is the one actually assigned.
*/
struct pro
{
char *p_name; /* name, eg -bl, -cli */
int p_type; /* type (int, bool, special) */
int p_default; /* the default value (if int) */
int p_special; /* depends on type */
int *p_obj; /* the associated variable */
} pro[] =
{
"T", PRO_SPECIAL, 0, KEY, 0,
"bacc", PRO_BOOL, false, ON, &bl_around,
"badp", PRO_BOOL, false, ON, &bl_at_proctop,
"bad", PRO_BOOL, false, ON, &bl_aft_decl,
"bap", PRO_BOOL, false, ON, &bl_a_procs,
"bbb", PRO_BOOL, false, ON, &bl_bef_bk,
"bc", PRO_BOOL, true, OFF, &ps.leave_comma,
"bl", PRO_BOOL, true, OFF, &btype_2,
"br", PRO_BOOL, true, ON, &btype_2,
"bs", PRO_BOOL, false, ON, &Bill_Shannon,
"cdb", PRO_BOOL, true, ON, &del_on_bl,
"cd", PRO_INT, 0, 0, &ps.decl_com_ind,
"ce", PRO_BOOL, true, ON, &cuddle_else,
"ci", PRO_INT, 0, 0, &continuation_indent,
"cli", PRO_SPECIAL, 0, CLI, 0,
"c", PRO_INT, 33, 0, &ps.com_ind,
"di", PRO_INT, 16, 0, &ps.decl_indent,
"dj", PRO_BOOL, false, ON, &ps.ljust_decl,
"d", PRO_INT, 0, 0, &ps.unindent_displace,
"eei", PRO_BOOL, false, ON, &ex_expr_indent,
"ei", PRO_BOOL, true, ON, &ps.else_if,
"fbc", PRO_FONT, 0, 0, (int *) &blkcomf,
"fbx", PRO_FONT, 0, 0, (int *) &boxcomf,
"fb", PRO_FONT, 0, 0, (int *) &bodyf,
"fc1", PRO_BOOL, true, ON, &format_col1_comments,
"fc", PRO_FONT, 0, 0, (int *) &scomf,
"fk", PRO_FONT, 0, 0, (int *) &keywordf,
"fs", PRO_FONT, 0, 0, (int *) &stringf,
"ip", PRO_BOOL, true, ON, &ps.indent_parameters,
"i", PRO_INT, 8, 0, &ps.ind_size,
"lc", PRO_INT, 0, 0, &bk_max_col,
"lp", PRO_BOOL, true, ON, &lineup_to_parens,
"l", PRO_INT, 78, 0, &max_col,
"nbacc", PRO_BOOL, false, OFF, &bl_around,
"nbadp", PRO_BOOL, false, OFF, &bl_at_proctop,
"nbad", PRO_BOOL, false, OFF, &bl_aft_decl,
"nbap", PRO_BOOL, false, OFF, &bl_a_procs,
"nbbb", PRO_BOOL, false, OFF, &bl_bef_bk,
"nbc", PRO_BOOL, true, ON, &ps.leave_comma,
"nbs", PRO_BOOL, false, OFF, &Bill_Shannon,
"ncdb", PRO_BOOL, true, OFF, &del_on_bl,
"nce", PRO_BOOL, true, OFF, &cuddle_else,
"ndj", PRO_BOOL, false, OFF, &ps.ljust_decl,
"neei", PRO_BOOL, false, OFF, &ex_expr_indent,
"nei", PRO_BOOL, true, OFF, &ps.else_if,
"nfc1", PRO_BOOL, true, OFF, &format_col1_comments,
"nip", PRO_BOOL, true, OFF, &ps.indent_parameters,
"nlp", PRO_BOOL, true, OFF, &lineup_to_parens,
"npcs", PRO_BOOL, false, OFF, &proc_calls_space,
"npro", PRO_SPECIAL, 0, IGN, 0,
"npsl", PRO_BOOL, true, OFF, &proc_str_line,
"nps", PRO_BOOL, false, OFF, &ptr_binop,
"nsc", PRO_BOOL, true, OFF, &star_comment_cont,
"nsob", PRO_BOOL, false, OFF, &swallow_opt_bl,
"nv", PRO_BOOL, false, OFF, &verbose,
"pcs", PRO_BOOL, false, ON, &proc_calls_space,
"psl", PRO_BOOL, true, ON, &proc_str_line,
"ps", PRO_BOOL, false, ON, &ptr_binop,
"sc", PRO_BOOL, true, ON, &star_comment_cont,
"sob", PRO_BOOL, false, ON, &swallow_opt_bl,
"st", PRO_SPECIAL, 0, STDIN, 0,
"troff", PRO_BOOL, false, ON, &troff,
"v", PRO_BOOL, false, ON, &verbose,
/* whew! */
0, 0, 0, 0, 0
};
/*
* set_profile reads $HOME/.indent.pro and ./.indent.pro and handles
* arguments given in these files.
*/
void set_profile()
{
register FILE *f;
char fname[BUFSIZ];
static char prof[] = ".indent.pro";
sprintf(fname, "%s/%s", getenv("HOME"), prof);
if ((f = fopen(fname, "r")) != NULL)
{
scan_profile(f);
(void) fclose(f);
}
if ((f = fopen(prof, "r")) != NULL)
{
scan_profile(f);
(void) fclose(f);
}
}
void scan_profile(f)
register FILE *f;
{
register int i;
register char *p;
char buf[BUFSIZ];
while (1)
{
for (p = buf; (i = getc(f)) != EOF && (*p = (char)i) > ' '; ++p);
if (p != buf)
{
*p++ = 0;
if (verbose)
printf("profile: %s\n", buf);
set_option(buf);
} else if (i == EOF)
return;
}
}
char *param_start;
int eqin(s1, s2)
register char *s1;
register char *s2;
{
while (*s1)
{
if (*s1++ != *s2++)
return (false);
}
param_start = s2;
return (true);
}
/*
* Set the defaults.
*/
void set_defaults()
{
register struct pro *p;
/* Because ps.case_indent is a float, we can't initialize it from
the table: */
ps.case_indent = 0; /* -cli0.0 */
for (p = pro; p->p_name; p++)
if (p->p_type != PRO_SPECIAL && p->p_type != PRO_FONT)
*p->p_obj = p->p_default;
}
void set_option(arg)
register char *arg;
{
register struct pro *p;
arg++; /* ignore leading "-" */
for (p = pro; p->p_name; p++)
if (*p->p_name == *arg && eqin(p->p_name, arg))
goto found;
fprintf(stderr, "indent: unknown parameter \"%s\"\n", arg - 1);
exit(1);
found:
switch (p->p_type)
{
case PRO_SPECIAL:
switch (p->p_special)
{
case IGN:
break;
case CLI:
if (*param_start == 0)
goto need_param;
ps.case_indent = atoi(param_start);
break;
case STDIN:
if (input == 0)
input = stdin;
if (output == 0)
output = stdout;
break;
case KEY:
if (*param_start == 0)
goto need_param;
{
register char *str = (char *) malloc(strlen(param_start) + 1);
strcpy(str, param_start);
addkey(str, 4);
}
break;
default:
fprintf(stderr, "\
indent: set_option: internal error: p_special %d\n", p->p_special);
exit(1);
}
break;
case PRO_BOOL:
if (p->p_special == OFF)
*p->p_obj = false;
else
*p->p_obj = true;
break;
case PRO_INT:
if (*param_start == 0)
{
need_param:
fprintf(stderr, "indent: ``%s'' requires a parameter\n",
arg - 1);
exit(1);
}
*p->p_obj = atoi(param_start);
break;
case PRO_FONT:
parsefont((struct fstate *) p->p_obj, param_start);
break;
default:
fprintf(stderr, "indent: set_option: internal error: p_type %d\n",
p->p_type);
exit(1);
}
}

View file

@ -1,54 +0,0 @@
/**
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980 The Regents of the University of California.
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley, the University of Illinois,
* Urbana, and Sun Microsystems, Inc. The name of either University
* or Sun Microsystems may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#)indent_codes.h 5.6 (Berkeley) 9/15/88
*/
#define newline 1
#define lparen 2
#define rparen 3
#define unary_op 4
#define binary_op 5
#define postop 6
#define question 7
#define casestmt 8
#define colon 9
#define semicolon 10
#define lbrace 11
#define rbrace 12
#define ident 13
#define comma 14
#define comment 15
#define swstmt 16
#define preesc 17
#define form_feed 18
#define decl 19
#define sp_paren 20
#define sp_nparen 21
#define ifstmt 22
#define whilestmt 23
#define forstmt 24
#define stmt 25
#define stmtl 26
#define elselit 27
#define dolit 28
#define dohead 29
#define ifhead 30
#define elsehead 31
#define period 32

View file

@ -1,457 +0,0 @@
/**
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980 The Regents of the University of California.
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley, the University of Illinois,
* Urbana, and Sun Microsystems, Inc. The name of either University
* or Sun Microsystems may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
* NAME: pr_comment
*
* FUNCTION: This routine takes care of scanning and printing comments.
*
* ALGORITHM: 1) Decide where the comment should be aligned, and if lines should
* be broken. 2) If lines should not be broken and filled, just copy up to
* end of comment. 3) If lines should be filled, then scan thru input_buffer
* copying characters to com_buf. Remember where the last blank, tab, or
* newline was. When line is filled, print up to last blank and continue
* copying.
*
* HISTORY: November 1976 D A Willcox of CAC Initial coding 12/6/76
* A Willcox of CAC Modification to handle UNIX-style comments
*
*/
/*
* this routine processes comments. It makes an attempt to keep comments
* from going over the max line length. If a line is too long, it moves
* everything from the last blank to the next comment line. Blanks and tabs
* from the beginning of the input line are removed
*/
#define PUBLIC extern
#include <stdlib.h>
#include "globs.h"
#include "proto.h"
void pr_comment()
{
int now_col; /* column we are in now */
int adj_max_col; /* Adjusted max_col for when we
* decide to spill comments
* over the right margin
*/
char *last_bl; /* points to the last blank in
* the output buffer
*/
char *t_ptr; /* used for moving string */
int unix_comment; /* tri-state variable used to
* decide if it is a unix-style
* comment. 0 means only blanks
* since / *, 1 means regular
* style comment, 2 means unix
* style comment
*/
int break_delim = del_on_bl;
int l_just_saw_decl = ps.just_saw_decl;
/* int ps.last_nl = 0; */ /* true iff the last
sig thing we have seen is a nl */
int one_liner = 1; /* true iff this comment is a
one-liner */
adj_max_col = max_col;
ps.just_saw_decl = 0;
last_bl = 0; /* no blanks found so far */
ps.box_com = false; /* at first, assume that we are
not in a boxed comment or
some other comment that
should not be touched */
++ps.out_coms; /* keep track of number of
comments */
unix_comment = 1; /* set flag to let us figure
out if there is a unix-style
comment ** DISABLED: use 0
to reenable this hack! */
/* Figure where to align and how to treat the comment */
if (ps.col_1 && !format_col1_comments)
{ /* if comment starts in column
1 it should not be touched */
ps.box_com = true;
ps.com_col = 1;
} else
{
if (*buf_ptr == '-' || *buf_ptr == '*')
{
ps.box_com = true; /* a comment with a '-' or '*'
immediately after the / * is
assumed to be a boxed
comment */
break_delim = 0;
}
if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code))
{
/* klg: check only if this line is blank */
/* If this (*and previous lines are*) blank, dont put comment
way out at left */
ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
adj_max_col = bk_max_col;
if (ps.com_col <= 1)
ps.com_col = 1 + !format_col1_comments;
} else
{
register target_col;
break_delim = 0;
if (s_code != e_code)
target_col = count_spaces(code_target(), s_code);
else
{
target_col = 1;
if (s_lab != e_lab)
target_col = count_spaces(label_target(), s_lab);
}
ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? ps.decl_com_ind : ps.com_ind;
if (ps.com_col < target_col)
ps.com_col = ((target_col + 7) & ~7) + 1;
if (ps.com_col + 24 > adj_max_col)
adj_max_col = ps.com_col + 24;
}
}
if (ps.box_com)
{
buf_ptr[-2] = 0;
ps.n_comment_delta = 1 - count_spaces(1, in_buffer);
buf_ptr[-2] = '/';
} else
{
ps.n_comment_delta = 0;
while (*buf_ptr == ' ' || *buf_ptr == '\t')
buf_ptr++;
}
ps.comment_delta = 0;
*e_com++ = '/'; /* put '/ *' into buffer */
*e_com++ = '*';
if (*buf_ptr != ' ' && !ps.box_com)
*e_com++ = ' ';
*e_com = '\0';
if (troff)
{
now_col = 1;
adj_max_col = 80;
} else
now_col = count_spaces(ps.com_col, s_com); /* figure what column we
would be in if we
printed the comment
now */
/* Start to copy the comment */
while (1)
{ /* this loop will go until the
comment is copied */
if (*buf_ptr > 040 && *buf_ptr != '*')
ps.last_nl = 0;
if (e_com >= l_com)
{
register nsize = l_com - s_com + 400;
combuf = (char *) realloc(combuf, nsize);
e_com = combuf + (e_com - s_com) + 1;
l_com = combuf + nsize - 5;
s_com = combuf + 1;
}
switch (*buf_ptr)
{ /* this checks for various spcl
cases */
case 014: /* check for a form feed */
if (!ps.box_com)
{ /* in a text comment, break the
line here */
ps.use_ff = true;
/* fix so dump_line uses a form feed */
dump_line();
last_bl = 0;
*e_com++ = ' ';
*e_com++ = '*';
*e_com++ = ' ';
while (*++buf_ptr == ' ' || *buf_ptr == '\t');
} else
{
if (++buf_ptr >= buf_end)
fill_buffer();
*e_com++ = 014;
}
break;
case '\n':
if (had_eof)
{ /* check for unexpected eof */
printf("Unterminated comment\n");
*e_com = '\0';
dump_line();
return;
}
one_liner = 0;
if (ps.box_com || ps.last_nl)
{ /* if this is a boxed comment,
we dont ignore the newline */
if (s_com == e_com)
{
*e_com++ = ' ';
*e_com++ = ' ';
}
*e_com = '\0';
if (!ps.box_com && e_com - s_com > 3)
{
if (break_delim == 1 && s_com[0] == '/'
&& s_com[1] == '*' && s_com[2] == ' ')
{
char *t = e_com;
break_delim = 2;
e_com = s_com + 2;
*e_com = 0;
if (bl_bef_bk)
prefix_blankline_requested = 1;
dump_line();
e_com = t;
s_com[0] = s_com[1] = s_com[2] = ' ';
}
dump_line();
if (e_com >= l_com)
{
register nsize = l_com - s_com + 400;
combuf = (char *) realloc(combuf, nsize);
e_com = combuf + (e_com - s_com) + 1;
l_com = combuf + nsize - 5;
s_com = combuf + 1;
}
*e_com++ = ' ';
*e_com++ = ' ';
}
dump_line();
now_col = ps.com_col;
} else
{
ps.last_nl = 1;
if (unix_comment != 1)
{ /* we not are in unix_style
comment */
if (unix_comment == 0 && s_code == e_code)
{
/* if it is a UNIX-style comment, ignore the
requirement that previous line be blank for
unindention */
ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
if (ps.com_col <= 1)
ps.com_col = 2;
}
unix_comment = 2; /* permanently remember that we
are in this type of comment */
dump_line();
++line_no;
now_col = ps.com_col;
*e_com++ = ' ';
/* fix so that the star at the start of the line will
line up */
do /* flush leading white space */
if (++buf_ptr >= buf_end)
fill_buffer();
while (*buf_ptr == ' ' || *buf_ptr == '\t');
break;
}
if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t')
last_bl = e_com - 1;
/* if there was a space at the end of the last line,
remember where it was */
else
{ /* otherwise, insert one */
last_bl = e_com;
*e_com++ = ' ';
if (e_com >= l_com)
{
register nsize = l_com - s_com + 400;
combuf = (char *) realloc(combuf, nsize);
e_com = combuf + (e_com - s_com) + 1;
l_com = combuf + nsize - 5;
s_com = combuf + 1;
}
++now_col;
}
}
++line_no; /* keep track of input line
number */
if (!ps.box_com)
{
int nstar = 1;
do
{ /* flush any blanks and/or tabs
at start of next line */
if (++buf_ptr >= buf_end)
fill_buffer();
if (*buf_ptr == '*' && --nstar >= 0)
{
if (++buf_ptr >= buf_end)
fill_buffer();
if (*buf_ptr == '/')
goto end_of_comment;
}
} while (*buf_ptr == ' ' || *buf_ptr == '\t');
} else if (++buf_ptr >= buf_end)
fill_buffer();
break; /* end of case for newline */
case '*': /* must check for possibility
of being at end of comment */
if (++buf_ptr >= buf_end) /* get to next char after * */
fill_buffer();
if (unix_comment == 0) /* set flag to show we are not
in unix-style comment */
unix_comment = 1;
if (*buf_ptr == '/')
{ /* it is the end!!! */
end_of_comment:
if (++buf_ptr >= buf_end)
fill_buffer();
if (*(e_com - 1) != ' ' && !ps.box_com)
{ /* insure blank before end */
*e_com++ = ' ';
++now_col;
}
if (break_delim == 1 && !one_liner && s_com[0] == '/'
&& s_com[1] == '*' && s_com[2] == ' ')
{
char *t = e_com;
break_delim = 2;
e_com = s_com + 2;
*e_com = 0;
if (bl_bef_bk)
prefix_blankline_requested = 1;
dump_line();
e_com = t;
s_com[0] = s_com[1] = s_com[2] = ' ';
}
if (break_delim == 2 && e_com > s_com + 3
/* now_col > adj_max_col - 2 && !ps.box_com */ )
{
*e_com = '\0';
dump_line();
now_col = ps.com_col;
}
if (e_com >= l_com)
{
register nsize = l_com - s_com + 400;
combuf = (char *) realloc(combuf, nsize);
e_com = combuf + (e_com - s_com) + 1;
l_com = combuf + nsize - 5;
s_com = combuf + 1;
}
*e_com++ = '*';
*e_com++ = '/';
*e_com = '\0';
ps.just_saw_decl = l_just_saw_decl;
return;
} else
{ /* handle isolated '*' */
*e_com++ = '*';
++now_col;
}
break;
default: /* we have a random char */
if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t')
unix_comment = 1; /* we are not in unix-style
comment */
*e_com = *buf_ptr++;
if (buf_ptr >= buf_end)
fill_buffer();
if (*e_com == '\t') /* keep track of column */
now_col = ((now_col - 1) & tabmask) + tabsize + 1;
else if (*e_com == '\b') /* this is a backspace */
--now_col;
else
++now_col;
if (*e_com == ' ' || *e_com == '\t')
last_bl = e_com;
/* remember we saw a blank */
++e_com;
if (now_col > adj_max_col && !ps.box_com && unix_comment == 1 && e_com[-1] > ' ')
{
/* the comment is too long, it must be broken up */
if (break_delim == 1 && s_com[0] == '/'
&& s_com[1] == '*' && s_com[2] == ' ')
{
char *t = e_com;
break_delim = 2;
e_com = s_com + 2;
*e_com = 0;
if (bl_bef_bk)
prefix_blankline_requested = 1;
dump_line();
e_com = t;
s_com[0] = s_com[1] = s_com[2] = ' ';
}
if (last_bl == 0)
{ /* we have seen no blanks */
last_bl = e_com; /* fake it */
*e_com++ = ' ';
}
*e_com = '\0'; /* print what we have */
*last_bl = '\0';
while (last_bl > s_com && last_bl[-1] < 040)
*--last_bl = 0;
e_com = last_bl;
dump_line();
*e_com++ = ' '; /* add blanks for continuation */
*e_com++ = ' ';
*e_com++ = ' ';
t_ptr = last_bl + 1;
last_bl = 0;
if (t_ptr >= e_com)
{
while (*t_ptr == ' ' || *t_ptr == '\t')
t_ptr++;
while (*t_ptr != '\0')
{ /* move unprinted part of
comment down in buffer */
if (*t_ptr == ' ' || *t_ptr == '\t')
last_bl = e_com;
*e_com++ = *t_ptr++;
}
}
*e_com = '\0';
now_col = count_spaces(ps.com_col, s_com); /* recompute current
position */
}
break;
}
}
}

View file

@ -1,308 +0,0 @@
/**
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980 The Regents of the University of California.
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley, the University of Illinois,
* Urbana, and Sun Microsystems, Inc. The name of either University
* or Sun Microsystems may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#)indent_globs.h 5.7 (Berkeley) 9/15/88
*/
#include <stdio.h>
#define BACKSLASH '\\'
#define bufsize 200 /* size of internal buffers */
#define inp_bufs 600 /* size of input buffer */
#define sc_size 5000 /* size of save_com buffer */
#define label_offset 2 /* number of levels a label is
placed to left of code */
#define tabsize 8 /* the size of a tab */
#define tabmask 0177770 /* mask used when figuring
length of lines with tabs */
#define false 0
#define true !false
PUBLIC FILE *input; /* the fid for the input file */
PUBLIC FILE *output; /* the output file */
PUBLIC char *labbuf; /* buffer for label */
PUBLIC char *s_lab; /* start ... */
PUBLIC char *e_lab; /* .. and end of stored label */
PUBLIC char *l_lab; /* limit of label buffer */
PUBLIC char *codebuf; /* buffer for code section */
PUBLIC char *s_code; /* start ... */
PUBLIC char *e_code; /* .. and end of stored code */
PUBLIC char *l_code; /* limit of code section */
PUBLIC char *combuf; /* buffer for comments */
PUBLIC char *s_com; /* start ... */
PUBLIC char *e_com; /* ... and end of stored
comments */
PUBLIC char *l_com; /* limit of comment buffer */
PUBLIC char in_buffer[inp_bufs]; /* input buffer */
PUBLIC char *buf_ptr; /* ptr to next character to be
taken from in_buffer */
PUBLIC char *buf_end; /* ptr to first after last char
in in_buffer */
PUBLIC char save_com[sc_size]; /* input text is saved here
when looking for the brace
after an if, while, etc */
PUBLIC char *sc_end; /* pointer into save_com buffer */
PUBLIC char *bp_save; /* saved value of buf_ptr when
taking input from save_com */
PUBLIC char *be_save; /* similarly saved value of
buf_end */
PUBLIC char token[bufsize]; /* the last token scanned */
PUBLIC int ptr_binop; /* pointer as binop */
PUBLIC int bl_aft_decl; /* blanklines after
declarations */
PUBLIC int bl_bef_bk; /* blanklines before
blockcomments */
PUBLIC int bl_a_procs; /* blanklines after procs */
PUBLIC int bl_around; /* blanklines around
conditional compilation */
PUBLIC int swallow_opt_bl; /* swallow optional blanklines */
PUBLIC int n_real_blanklines;
PUBLIC int prefix_blankline_requested;
PUBLIC int postfix_blankline_requested;
PUBLIC int break_comma; /* when true and not in parens,
break after a comma */
PUBLIC int btype_2; /* when true, brace should be
on same line as if, while,
etc */
PUBLIC long case_ind; /* indentation level to be used
for a "case n:" */
PUBLIC int code_lines; /* count of lines with code */
PUBLIC int had_eof; /* set to true when input is
exhausted */
PUBLIC int line_no; /* the current line number. */
PUBLIC int max_col; /* the maximum allowable line
length */
PUBLIC int verbose; /* when true, non-essential
error messages are printed */
PUBLIC int cuddle_else; /* true if else should cuddle
up to '}' */
PUBLIC int star_comment_cont; /* true iff comment
continuation lines should
have stars at the beginning
of each line. */
PUBLIC int del_on_bl; /* comment_delimiter_on_blanklin
e */
PUBLIC int troff; /* true iff were generating
troff input */
PUBLIC int proc_str_line; /* if true, the names of
procedures being defined get
placed in column 1 (ie. a
newline is placed between
the type of the procedure
and its name) */
PUBLIC int proc_calls_space; /* If true, procedure calls
look like: foo(bar) rather
than foo (bar) */
PUBLIC int format_col1_comments; /* If comments which start in
column 1 are to be magically
reformatted (just like
comments that begin in later
columns) */
PUBLIC int inhibit_formatting; /* true if INDENT OFF is in
effect */
PUBLIC int suppress_blanklines; /* set iff following blanklines
should be suppressed */
PUBLIC int continuation_indent; /* set to the indentation
between the edge of code and
continuation lines */
PUBLIC int lineup_to_parens; /* if true, continued code
within parens will be lined
up to the open paren */
PUBLIC int Bill_Shannon; /* true iff a blank should
always be inserted after
sizeof */
PUBLIC int bl_at_proctop; /* This is vaguely similar to
blanklines_after_declarations
except that it only applies
to the first set of
declarations in a procedure
(just after the first '{')
and it causes a blank line
to be generated even if
there are no declarations */
PUBLIC int bk_max_col;
PUBLIC int ex_expr_indent; /* True if continuation lines
from the expression part of
"if(e)", "while(e)",
"for(e;e;e)" should be
indented an extra tab stop
so that they don't conflict
with the code that follows */
/* -troff font state information */
struct fstate
{
char font[4];
char size;
int allcaps;
};
PUBLIC struct fstate
keywordf, /* keyword font */
stringf, /* string font */
boxcomf, /* Box comment font */
blkcomf, /* Block comment font */
scomf, /* Same line comment font */
bodyf; /* major body font */
#define STACKSIZE 150
PUBLIC struct parser_state
{
int last_token;
struct fstate cfont; /* Current font */
int p_stack[STACKSIZE]; /* this is the parsers stack */
int il[STACKSIZE]; /* this stack stores
indentation levels */
long cstk[STACKSIZE]; /* used to store case stmt
indentation levels */
int box_com; /* set to true when we are in a
"boxed" comment. In that
case, the first non-blank
char should be lined up with
the / in / * */
int comment_delta, n_comment_delta;
int cast_mask; /* indicates which close parens
close off casts */
int sizeof_mask; /* indicates which close parens
close off sizeof''s */
int block_init; /* true iff inside a block
initialization */
int block_init_level; /* The level of brace nesting
in an initialization */
int last_nl; /* this is true if the last
thing scanned was a newline */
int in_or_st; /* Will be true iff there has
been a declarator (e.g. int
or char) and no left paren
since the last semicolon.
When true, a '{' is starting
a structure definition or an
initialization list */
int bl_line; /* set to 1 by dump_line if the
line is blank */
int col_1; /* set to true if the last
token started in column 1 */
int com_col; /* this is the column in which
the current coment should
start */
int com_ind; /* the column in which comments
to the right of code should
start */
int com_lines; /* the number of lines with
comments, set by dump_line */
int dec_nest; /* current nesting level for
structure or init */
int decl_com_ind; /* the column in which comments
after declarations should be
put */
int decl_on_line; /* set to true if this line of
code has part of a
declaration on it */
int i_l_follow; /* the level to which ind_level
should be set after the
current line is printed */
int in_decl; /* set to true when we are in a
declaration stmt. The
processing of braces is then
slightly different */
int in_stmt; /* set to 1 while in a stmt */
int ind_level; /* the current indentation
level */
int ind_size; /* the size of one indentation
level */
int ind_stmt; /* set to 1 if next line should
have an extra indentation
level because we are in the
middle of a stmt */
int last_u_d; /* set to true after scanning a
token which forces a
following operator to be
unary */
int leave_comma; /* if true, never break
declarations after commas */
int ljust_decl; /* true if declarations should
be left justified */
int out_coms; /* the number of comments
processed, set by pr_comment */
int out_lines; /* the number of lines written,
set by dump_line */
int p_l_follow; /* used to remember how to
indent following statement */
int paren_level; /* parenthesization level. used
to indent within stmts */
short paren_indents[20]; /* column positions of each
paren */
int pcase; /* set to 1 if the current line
label is a case. It is
printed differently from a
regular label */
int search_brace; /* set to true by parse when it
is necessary to buffer up
all info up to the start of
a stmt after an if, while,
etc */
int unindent_displace; /* comments not to the right of
code will be placed this
many indentation levels to
the left of code */
int use_ff; /* set to one if the current
line should be terminated
with a form feed */
int want_blank; /* set to true when the
following token should be
prefixed by a blank. (Said
prefixing is ignored in some
cases.) */
int else_if; /* True iff else if pairs
should be handled specially */
int decl_indent; /* column to indent declared
identifiers to */
int its_a_keyword;
int sizeof_keyword;
int dumped_decl_indent;
int case_indent; /* The distance to indent case
labels from the switch
statement */
int in_par_decl;
int indent_parameters;
int tos; /* pointer to top of stack */
char procname[100]; /* The name of the current
procedure */
int just_saw_decl;
} ps;
PUBLIC int ifdef_level;
PUBLIC struct parser_state state_stack[5];
PUBLIC struct parser_state match_state[5];

File diff suppressed because it is too large Load diff

View file

@ -1 +0,0 @@
-bap -bbb -br -ncdb -cli0.5 -di1 -lp -npsl -nfc1 -nip

View file

@ -1,636 +0,0 @@
/**
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980 The Regents of the University of California.
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley, the University of Illinois,
* Urbana, and Sun Microsystems, Inc. The name of either University
* or Sun Microsystems may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#define PUBLIC extern
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "globs.h"
#include "proto.h"
int comment_open;
static paren_target;
void dump_line()
{ /* dump_line is the routine
that actually effects the
printing of the new source.
It prints the label section,
followed by the code section
with the appropriate nesting
level, followed by any
comments */
register int cur_col, target_col;
static not_first_line;
if (ps.procname[0])
{
if (troff)
{
if (comment_open)
{
comment_open = 0;
fprintf(output, ".*/\n");
}
fprintf(output, ".Pr \"%s\"\n", ps.procname);
}
ps.ind_level = 0;
ps.procname[0] = 0;
}
if (s_code == e_code && s_lab == e_lab && s_com == e_com)
{
if (suppress_blanklines > 0)
suppress_blanklines--;
else
{
ps.bl_line = true;
n_real_blanklines++;
}
} else if (!inhibit_formatting)
{
suppress_blanklines = 0;
ps.bl_line = false;
if (prefix_blankline_requested && not_first_line)
if (swallow_opt_bl)
{
if (n_real_blanklines == 1)
n_real_blanklines = 0;
} else
{
if (n_real_blanklines == 0)
n_real_blanklines = 1;
}
while (--n_real_blanklines >= 0)
putc('\n', output);
n_real_blanklines = 0;
if (ps.ind_level == 0)
ps.ind_stmt = 0; /* this is a class A kludge.
dont do additional statement
indentation if we are at
bracket level 0 */
if (e_lab != s_lab || e_code != s_code)
++code_lines; /* keep count of lines with
code */
if (e_lab != s_lab)
{ /* print lab, if any */
if (comment_open)
{
comment_open = 0;
fprintf(output, ".*/\n");
}
while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
e_lab--;
cur_col = pad_output(1, label_target());
fprintf(output, "%.*s", (int)(e_lab - s_lab), s_lab);
cur_col = count_spaces(cur_col, s_lab);
} else
cur_col = 1; /* there is no label section */
ps.pcase = false;
if (s_code != e_code)
{ /* print code section, if any */
register char *p;
if (comment_open)
{
comment_open = 0;
fprintf(output, ".*/\n");
}
target_col = code_target();
{
register i;
for (i = 0; i < ps.p_l_follow; i++)
if (ps.paren_indents[i] >= 0)
ps.paren_indents[i] = -(ps.paren_indents[i] + target_col);
}
cur_col = pad_output(cur_col, target_col);
for (p = s_code; p < e_code; p++)
if (*p == (char) 0200)
fprintf(output, "%d", target_col * 7);
else
putc(*p, output);
cur_col = count_spaces(cur_col, s_code);
}
if (s_com != e_com)
if (troff)
{
int all_here = 0;
register char *p;
if (e_com[-1] == '/' && e_com[-2] == '*')
e_com -= 2, all_here++;
while (e_com > s_com && e_com[-1] == ' ')
e_com--;
*e_com = 0;
p = s_com;
while (*p == ' ')
p++;
if (p[0] == '/' && p[1] == '*')
p += 2, all_here++;
else if (p[0] == '*')
p += p[1] == '/' ? 2 : 1;
while (*p == ' ')
p++;
if (*p == 0)
goto inhibit_newline;
if (comment_open < 2 && ps.box_com)
{
comment_open = 0;
fprintf(output, ".*/\n");
}
if (comment_open == 0)
{
if ('a' <= *p && *p <= 'z')
*p = *p + 'A' - 'a';
if (e_com - p < 50 && all_here == 2)
{
register char *follow = p;
fprintf(output, "\n.nr C! \\w\1");
while (follow < e_com)
{
switch (*follow)
{
case '\n':
putc(' ', output);
case 1:
break;
case '\\':
putc('\\', output);
default:
putc(*follow, output);
}
follow++;
}
putc(1, output);
}
fprintf(output, "\n./* %dp %d %dp\n",
ps.com_col * 7,
(s_code != e_code || s_lab != e_lab) - ps.box_com,
target_col * 7);
}
comment_open = 1 + ps.box_com;
while (*p)
{
if (*p == BACKSLASH)
putc(BACKSLASH, output);
putc(*p++, output);
}
} else
{ /* print comment, if any */
register target = ps.com_col;
register char *com_st = s_com;
target += ps.comment_delta;
while (*com_st == '\t')
com_st++, target += 8; /* ? */
while (target <= 0)
if (*com_st == ' ')
target++, com_st++;
else if (*com_st == '\t')
target = ((target - 1) & ~7) + 9, com_st++;
else
target = 1;
if (cur_col > target)
{ /* if comment cant fit on this
line, put it on next line */
putc('\n', output);
cur_col = 1;
++ps.out_lines;
}
while (e_com > com_st && isspace(e_com[-1]))
e_com--;
cur_col = pad_output(cur_col, target);
if (!ps.box_com)
{
if (star_comment_cont && (com_st[1] != '*' || e_com <= com_st + 1))
if (com_st[1] == ' ' && com_st[0] == ' ' && e_com > com_st + 1)
com_st[1] = '*';
else
fwrite(" * ", com_st[0] == '\t' ? 2 : com_st[0] == '*' ? 1 : 3, 1, output);
}
fwrite(com_st, (int)(e_com - com_st), 1, output);
ps.comment_delta = ps.n_comment_delta;
cur_col = count_spaces(cur_col, com_st);
++ps.com_lines; /* count lines with comments */
}
if (ps.use_ff)
putc('\014', output);
else
putc('\n', output);
inhibit_newline:
++ps.out_lines;
if (ps.just_saw_decl == 1 && bl_aft_decl)
{
prefix_blankline_requested = 1;
ps.just_saw_decl = 0;
} else
prefix_blankline_requested = postfix_blankline_requested;
postfix_blankline_requested = 0;
}
ps.decl_on_line = ps.in_decl; /* if we are in the middle of a
declaration, remember that
fact for proper comment
indentation */
ps.ind_stmt = ps.in_stmt & ~ps.in_decl; /* next line should be
indented if we have
not completed this
stmt and if we are
not in the middle of
a declaration */
ps.use_ff = false;
ps.dumped_decl_indent = 0;
*(e_lab = s_lab) = '\0'; /* reset buffers */
*(e_code = s_code) = '\0';
*(e_com = s_com) = '\0';
ps.ind_level = ps.i_l_follow;
ps.paren_level = ps.p_l_follow;
paren_target = -ps.paren_indents[ps.paren_level - 1];
not_first_line = 1;
return;
}
int code_target()
{
register target_col = ps.ind_size * ps.ind_level + 1;
if (ps.paren_level)
if (!lineup_to_parens)
target_col += continuation_indent * ps.paren_level;
else
{
register w;
register t = paren_target;
if ((w = count_spaces(t, s_code) - max_col) > 0
&& count_spaces(target_col, s_code) <= max_col)
{
t -= w + 1;
if (t > target_col)
target_col = t;
} else
target_col = t;
}
else if (ps.ind_stmt)
target_col += continuation_indent;
return target_col;
}
int label_target()
{
return
ps.pcase ? (int) (case_ind * ps.ind_size) + 1
: *s_lab == '#' ? 1
: ps.ind_size * (ps.ind_level - label_offset) + 1;
}
/*
* Copyright (C) 1976 by the Board of Trustees of the University of Illinois
*
* All rights reserved
*
*
* NAME: fill_buffer
*
* FUNCTION: Reads one block of input into input_buffer
*
* HISTORY: initial coding November 1976 D A Willcox of CAC 1/7/77 A
* Willcox of CAC Added check for switch back to partly full input
* buffer from temporary buffer
*
*/
void
fill_buffer()
{ /* this routine reads stuff
from the input */
register char *p;
register int i;
register FILE *f = input;
if (bp_save != 0)
{ /* there is a partly filled
input buffer left */
buf_ptr = bp_save; /* dont read anything, just
switch buffers */
buf_end = be_save;
bp_save = be_save = 0;
if (buf_ptr < buf_end)
return; /* only return if there is
really something in this
buffer */
}
for (p = buf_ptr = in_buffer;;)
{
if ((i = getc(f)) == EOF)
{
*p++ = ' ';
*p++ = '\n';
had_eof = true;
break;
}
*p++ = (char)i;
if (i == '\n')
break;
}
buf_end = p;
if (p[-2] == '/' && p[-3] == '*')
{
if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0)
fill_buffer(); /* flush indent error message */
else
{
int com = 0;
p = in_buffer;
while (*p == ' ' || *p == '\t')
p++;
if (*p == '/' && p[1] == '*')
{
p += 2;
while (*p == ' ' || *p == '\t')
p++;
if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E'
&& p[4] == 'N' && p[5] == 'T')
{
p += 6;
while (*p == ' ' || *p == '\t')
p++;
if (*p == '*')
com = 1;
else if (*p == 'O')
if (*++p == 'N')
p++, com = 1;
else if (*p == 'F' && *++p == 'F')
p++, com = 2;
while (*p == ' ' || *p == '\t')
p++;
if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com)
{
if (s_com != e_com || s_lab != e_lab || s_code != e_code)
dump_line();
if (!(inhibit_formatting = com - 1))
{
n_real_blanklines = 0;
postfix_blankline_requested = 0;
prefix_blankline_requested = 0;
suppress_blanklines = 1;
}
}
}
}
}
}
if (inhibit_formatting)
{
p = in_buffer;
do
putc(*p, output);
while (*p++ != '\n');
}
return;
}
/*
* Copyright (C) 1976 by the Board of Trustees of the University of Illinois
*
* All rights reserved
*
*
* NAME: pad_output
*
* FUNCTION: Writes tabs and spaces to move the current column up to the desired
* position.
*
* ALGORITHM: Put tabs and/or blanks into pobuf, then write pobuf.
*
* PARAMETERS: current integer The current column target
* nteger The desired column
*
* RETURNS: Integer value of the new column. (If current >= target, no action
* is taken, and current is returned.
*
* GLOBALS: None
*
* CALLS: write (sys)
*
* CALLED BY: dump_line
*
* HISTORY: initial coding November 1976 D A Willcox of CAC
*
*/
int pad_output(current, target) /* writes tabs and blanks (if
necessary) to get the
current output position up
to the target column */
int current; /* the current column value */
int target; /* position we want it at */
{
register int curr; /* internal column pointer */
register int tcur;
if (troff)
fprintf(output, "\\h'|%dp'", (target - 1) * 7);
else
{
if (current >= target)
return (current); /* line is already long enough */
curr = current;
while ((tcur = ((curr - 1) & tabmask) + tabsize + 1) <= target)
{
putc('\t', output);
curr = tcur;
}
while (curr++ < target)
putc(' ', output); /* pad with final blanks */
}
return (target);
}
/*
* Copyright (C) 1976 by the Board of Trustees of the University of Illinois
*
* All rights reserved
*
*
* NAME: count_spaces
*
* FUNCTION: Find out where printing of a given string will leave the current
* character position on output.
*
* ALGORITHM: Run thru input string and add appropriate values to current
* position.
*
* RETURNS: Integer value of position after printing "buffer" starting in column
* "current".
*
* HISTORY: initial coding November 1976 D A Willcox of CAC
*
*/
int
count_spaces(current, buffer)
/*
* this routine figures out where the character position will be after
* printing the text in buffer starting at column "current"
*/
int current;
char *buffer;
{
register char *buf; /* used to look thru buffer */
register int cur; /* current character counter */
cur = current;
for (buf = buffer; *buf != '\0'; ++buf)
{
switch (*buf)
{
case '\n':
case 014: /* form feed */
cur = 1;
break;
case '\t':
cur = ((cur - 1) & tabmask) + tabsize + 1;
break;
case '': /* this is a backspace */
--cur;
break;
default:
++cur;
break;
} /* end of switch */
} /* end of for loop */
return (cur);
}
int found_err;
void diag(level, msg, a, b)
int level;
char *msg;
int a, b;
{
if (level)
found_err = 1;
if (output == stdout)
{
fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no);
fprintf(stdout, msg, a, b);
fprintf(stdout, " */\n");
} else
{
fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no);
fprintf(stderr, msg, a, b);
fprintf(stderr, "\n");
}
}
void writefdef(f, nm)
register struct fstate *f;
int nm;
{
fprintf(output, ".ds f%c %s\n.nr s%c %d\n",
nm, f->font, nm, f->size);
}
char *
chfont(of, nf, s)
register struct fstate *of, *nf;
char *s;
{
if (of->font[0] != nf->font[0]
|| of->font[1] != nf->font[1])
{
*s++ = '\\';
*s++ = 'f';
if (nf->font[1])
{
*s++ = '(';
*s++ = nf->font[0];
*s++ = nf->font[1];
} else
*s++ = nf->font[0];
}
if (nf->size != of->size)
{
*s++ = '\\';
*s++ = 's';
if (nf->size < of->size)
{
*s++ = '-';
*s++ = (char)'0' + of->size - nf->size;
} else
{
*s++ = '+';
*s++ = (char)'0' + nf->size - of->size;
}
}
return s;
}
void parsefont(f, s0)
register struct fstate *f;
char *s0;
{
register char *s = s0;
int sizedelta = 0;
memset(f, '\0', sizeof *f);
while (*s)
{
if (isdigit(*s))
f->size = f->size * 10 + *s - '0';
else if (isupper(*s))
if (f->font[0])
f->font[1] = *s;
else
f->font[0] = *s;
else if (*s == 'c')
f->allcaps = 1;
else if (*s == '+')
sizedelta++;
else if (*s == '-')
sizedelta--;
else
{
fprintf(stderr, "indent: bad font specification: %s\n", s0);
exit(1);
}
s++;
}
if (f->font[0] == 0)
f->font[0] = 'R';
if (bodyf.size == 0)
bodyf.size = 11;
if (f->size == 0)
f->size = bodyf.size + sizedelta;
else if (sizedelta > 0)
f->size += bodyf.size;
else
f->size = bodyf.size - f->size;
}

View file

@ -1,571 +0,0 @@
/**
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980 The Regents of the University of California.
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley, the University of Illinois,
* Urbana, and Sun Microsystems, Inc. The name of either University
* or Sun Microsystems may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
* Here we have the token scanner for indent. It scans off one token and
* puts it in the global variable "token". It returns a code, indicating the
* type of token scanned.
*/
#define PUBLIC extern
#include <ctype.h>
#include <string.h>
#include "globs.h"
#include "codes.h"
#include "proto.h"
#define alphanum 1
#define opchar 3
struct templ
{
char *rwd;
int rwcode;
};
struct templ specials[100] =
{
"switch", 1,
"case", 2,
"break", 0,
"struct", 3,
"union", 3,
"enum", 3,
"default", 2,
"int", 4,
"char", 4,
"float", 4,
"double", 4,
"long", 4,
"short", 4,
"typedef", 4,
"unsigned", 4,
"register", 4,
"static", 4,
"global", 4,
"extern", 4,
"void", 4,
"goto", 0,
"return", 0,
"if", 5,
"while", 5,
"for", 5,
"else", 6,
"do", 6,
"sizeof", 7,
0, 0
};
char chartype[128] =
{ /* this is used to facilitate
the decision of what type
(alphanumeric, operator)
each character is */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 3, 0, 0, 1, 3, 3, 0,
0, 0, 3, 3, 0, 3, 0, 3,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 0, 0, 3, 3, 3, 3,
0, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 0, 0, 3, 1,
0, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 3, 0, 3, 0
};
int
lexi()
{
register char *tok; /* local pointer to next char
in token */
int unary_delim; /* this is set to 1 if the
current token
forces a following operator to
be unary */
static int last_code; /* the last token type returned */
static int l_struct; /* set to 1 if the last token
was 'struct' */
int code; /* internal code to be returned */
char qchar; /* the delimiter character for
a string */
tok = token; /* point to start of place to
save token */
unary_delim = false;
ps.col_1 = ps.last_nl; /* tell world that this token
started in column 1 iff the
last thing scanned was nl */
ps.last_nl = false;
while (*buf_ptr == ' ' || *buf_ptr == '\t')
{ /* get rid of blanks */
ps.col_1 = false; /* leading blanks imply token
is not in column 1 */
if (++buf_ptr >= buf_end)
fill_buffer();
}
/* Scan an alphanumeric token */
if (chartype[*buf_ptr] == alphanum || (buf_ptr[0] == '.' && isdigit(buf_ptr[1])))
{
/* we have a character or number */
register char *j; /* used for searching thru list
of
reserved words */
register struct templ *p;
if (isdigit(*buf_ptr) || (buf_ptr[0] == '.' && isdigit(buf_ptr[1])))
{
int seendot = 0, seenexp = 0;
if (*buf_ptr == '0' &&
(buf_ptr[1] == 'x' || buf_ptr[1] == 'X'))
{
*tok++ = *buf_ptr++;
*tok++ = *buf_ptr++;
while (isxdigit(*buf_ptr))
*tok++ = *buf_ptr++;
} else
while (1)
{
if (*buf_ptr == '.')
if (seendot)
break;
else
seendot++;
*tok++ = *buf_ptr++;
if (!isdigit(*buf_ptr) && *buf_ptr != '.')
if ((*buf_ptr != 'E' && *buf_ptr != 'e') || seenexp)
break;
else
{
seenexp++;
seendot++;
*tok++ = *buf_ptr++;
if (*buf_ptr == '+' || *buf_ptr == '-')
*tok++ = *buf_ptr++;
}
}
if (*buf_ptr == 'L' || *buf_ptr == 'l')
*tok++ = *buf_ptr++;
} else
while (chartype[*buf_ptr] == alphanum)
{ /* copy it over */
*tok++ = *buf_ptr++;
if (buf_ptr >= buf_end)
fill_buffer();
}
*tok++ = '\0';
while (*buf_ptr == ' ' || *buf_ptr == '\t')
{ /* get rid of blanks */
if (++buf_ptr >= buf_end)
fill_buffer();
}
ps.its_a_keyword = false;
ps.sizeof_keyword = false;
if (l_struct)
{ /* if last token was 'struct',
then this token should be
treated as a declaration */
l_struct = false;
last_code = ident;
ps.last_u_d = true;
return (decl);
}
ps.last_u_d = false; /* Operator after indentifier
is binary */
last_code = ident; /* Remember that this is the
code we will return */
/* This loop will check if the token is a keyword. */
for (p = specials; (j = p->rwd) != 0; p++)
{
tok = token; /* point at scanned token */
if (*j++ != *tok++ || *j++ != *tok++)
continue; /* This test depends on the
fact that identifiers are
always at least 1 character
long (ie. the first two
bytes of the identifier are
always meaningful) */
if (tok[-1] == 0)
break; /* If its a one-character
identifier */
while (*tok++ == *j)
if (*j++ == 0)
goto found_keyword; /* I wish that C had a
multi-level break... */
}
if (p->rwd)
{ /* we have a keyword */
found_keyword:
ps.its_a_keyword = true;
ps.last_u_d = true;
switch (p->rwcode)
{
case 1: /* it is a switch */
return (swstmt);
case 2: /* a case or default */
return (casestmt);
case 3: /* a "struct" */
if (ps.p_l_follow)
break; /* inside parens: cast */
l_struct = true;
/* Next time around, we will want to know that we have had
a 'struct' */
case 4: /* one of the declaration
keywords */
if (ps.p_l_follow)
{
ps.cast_mask |= 1 << ps.p_l_follow;
break; /* inside parens: cast */
}
last_code = decl;
return (decl);
case 5: /* if, while, for */
return (sp_paren);
case 6: /* do, else */
return (sp_nparen);
case 7:
ps.sizeof_keyword = true;
default: /* all others are treated like
any other identifier */
return (ident);
} /* end of switch */
} /* end of if (found_it) */
if (*buf_ptr == '(' && ps.tos <= 1 && ps.ind_level == 0)
{
register char *tp = buf_ptr;
while (tp < buf_end)
if (*tp++ == ')' && *tp == ';')
goto not_proc;
strncpy(ps.procname, token, sizeof ps.procname - 1);
ps.in_par_decl = 1;
not_proc:;
}
/* The following hack attempts to guess whether or not the
current token is in fact a declaration keyword -- one that has
been typedefd */
if (((*buf_ptr == '*' && buf_ptr[1] != '=') || isalpha(*buf_ptr) || *buf_ptr == '_')
&& !ps.p_l_follow
&& !ps.block_init
&& (ps.last_token == rparen || ps.last_token == semicolon ||
ps.last_token == decl ||
ps.last_token == lbrace || ps.last_token == rbrace))
{
ps.its_a_keyword = true;
ps.last_u_d = true;
last_code = decl;
return decl;
}
if (last_code == decl) /* if this is a declared
variable, then following
sign is unary */
ps.last_u_d = true; /* will make "int a -1" work */
last_code = ident;
return (ident); /* the ident is not in the list */
} /* end of procesing for alpanum
character */
/* l l l Scan a non-alphanumeric token */
*tok++ = *buf_ptr; /* if it is only a
one-character token, it is
moved here */
*tok = '\0';
if (++buf_ptr >= buf_end)
fill_buffer();
switch (*token)
{
case '\n':
unary_delim = ps.last_u_d;
ps.last_nl = true; /* remember that we just had a
newline */
code = (had_eof ? 0 : newline);
/* if data has been exausted, the newline is a dummy, and we
should return code to stop */
break;
case '\'': /* start of quoted character */
case '"': /* start of string */
qchar = *token;
if (troff)
{
tok[-1] = '`';
if (qchar == '"')
*tok++ = '`';
tok = chfont(&bodyf, &stringf, tok);
}
do
{ /* copy the string */
while (1)
{ /* move one character or
[/<char>]<char> */
if (*buf_ptr == '\n')
{
printf("%d: Unterminated literal\n", line_no);
goto stop_lit;
}
*tok = *buf_ptr++;
if (buf_ptr >= buf_end)
fill_buffer();
if (had_eof || ((tok - token) > (bufsize - 2)))
{
printf("Unterminated literal\n");
++tok;
goto stop_lit;
/* get outof literal copying loop */
}
if (*tok == BACKSLASH)
{ /* if escape, copy extra char */
if (*buf_ptr == '\n') /* check for escaped newline */
++line_no;
if (troff)
{
*++tok = BACKSLASH;
if (*buf_ptr == BACKSLASH)
*++tok = BACKSLASH;
}
*++tok = *buf_ptr++;
++tok; /* we must increment this again
because we copied two chars */
if (buf_ptr >= buf_end)
fill_buffer();
} else
break; /* we copied one character */
} /* end of while (1) */
} while (*tok++ != qchar);
if (troff)
{
tok = chfont(&stringf, &bodyf, tok - 1);
if (qchar == '"')
*tok++ = '\'';
}
stop_lit:
code = ident;
break;
case ('('):
case ('['):
unary_delim = true;
code = lparen;
break;
case (')'):
case (']'):
code = rparen;
break;
case '#':
unary_delim = ps.last_u_d;
code = preesc;
break;
case '?':
unary_delim = true;
code = question;
break;
case (':'):
code = colon;
unary_delim = true;
break;
case (';'):
unary_delim = true;
code = semicolon;
break;
case ('{'):
unary_delim = true;
/* if (ps.in_or_st) ps.block_init = 1; */
code = ps.block_init ? lparen : lbrace;
break;
case ('}'):
unary_delim = true;
code = ps.block_init ? rparen : rbrace;
break;
case 014: /* a form feed */
unary_delim = ps.last_u_d;
ps.last_nl = true; /* remember this so we can set
'ps.col_1' right */
code = form_feed;
break;
case (','):
unary_delim = true;
code = comma;
break;
case '.':
unary_delim = false;
code = period;
break;
case '-':
case '+': /* check for -, +, --, ++ */
code = (ps.last_u_d ? unary_op : binary_op);
unary_delim = true;
if (*buf_ptr == token[0])
{
/* check for doubled character */
*tok++ = *buf_ptr++;
/* buffer overflow will be checked at end of loop */
if (last_code == ident || last_code == rparen)
{
code = (ps.last_u_d ? unary_op : postop);
/* check for following ++ or -- */
unary_delim = false;
}
} else if (*buf_ptr == '=')
/* check for operator += */
*tok++ = *buf_ptr++;
else if (*buf_ptr == '>')
{
/* check for operator -> */
*tok++ = *buf_ptr++;
if (!ptr_binop)
{
unary_delim = false;
code = unary_op;
ps.want_blank = false;
}
}
break; /* buffer overflow will be
checked at end of switch */
case '=':
if (ps.in_or_st)
ps.block_init = 1;
#ifdef undef
if (chartype[*buf_ptr] == opchar)
{ /* we have two char assignment */
tok[-1] = *buf_ptr++;
if ((tok[-1] == '<' || tok[-1] == '>') && tok[-1] == *buf_ptr)
*tok++ = *buf_ptr++;
*tok++ = '='; /* Flip =+ to += */
*tok = 0;
}
#else
if (*buf_ptr == '=')
{ /* == */
*tok++ = '='; /* Flip =+ to += */
buf_ptr++;
*tok = 0;
}
#endif
code = binary_op;
unary_delim = true;
break;
/* can drop thru!!! */
case '>':
case '<':
case '!': /* ops like <, <<, <=, !=, etc */
if (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=')
{
*tok++ = *buf_ptr;
if (++buf_ptr >= buf_end)
fill_buffer();
}
if (*buf_ptr == '=')
*tok++ = *buf_ptr++;
code = (ps.last_u_d ? unary_op : binary_op);
unary_delim = true;
break;
default:
if (token[0] == '/' && *buf_ptr == '*')
{
/* it is start of comment */
*tok++ = '*';
if (++buf_ptr >= buf_end)
fill_buffer();
code = comment;
unary_delim = ps.last_u_d;
break;
}
while (*(tok - 1) == *buf_ptr || *buf_ptr == '=')
{
/* handle ||, &&, etc, and also things as in int *****i */
*tok++ = *buf_ptr;
if (++buf_ptr >= buf_end)
fill_buffer();
}
code = (ps.last_u_d ? unary_op : binary_op);
unary_delim = true;
} /* end of switch */
if (code != newline)
{
l_struct = false;
last_code = code;
}
if (buf_ptr >= buf_end) /* check for input buffer empty */
fill_buffer();
ps.last_u_d = unary_delim;
*tok = '\0'; /* null terminate the token */
return (code);
}
/*
* Add the given keyword to the keyword table, using val as the keyword type
*/
void addkey(key, val)
char *key;
int val;
{
register struct templ *p = specials;
while (p->rwd)
if (p->rwd[0] == key[0] && strcmp(p->rwd, key) == 0)
return;
else
p++;
if (p >= specials + sizeof specials / sizeof specials[0])
return; /* For now, table overflows are
silently ignored */
p->rwd = key;
p->rwcode = val;
p[1].rwd = 0;
p[1].rwcode = 0;
return;
}

View file

@ -1,319 +0,0 @@
/**
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980 The Regents of the University of California.
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley, the University of Illinois,
* Urbana, and Sun Microsystems, Inc. The name of either University
* or Sun Microsystems may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#define PUBLIC extern
#include "./globs.h"
#include "./codes.h"
#include "proto.h"
void parse(tk)
int tk; /* the code for the construct
scanned */
{
int i;
#ifdef debug
printf("%2d - %s\n", tk, token);
#endif
while (ps.p_stack[ps.tos] == ifhead && tk != elselit)
{
/* true if we have an if without an else */
ps.p_stack[ps.tos] = stmt; /* apply the if(..) stmt ::=
stmt reduction */
reduce(); /* see if this allows any
reduction */
}
switch (tk)
{ /* go on and figure out what to
do with the input */
case decl: /* scanned a declaration word */
ps.search_brace = btype_2;
/* indicate that following brace should be on same line */
if (ps.p_stack[ps.tos] != decl)
{ /* only put one declaration
onto stack */
break_comma = true; /* while in declaration,
newline should be forced
after comma */
ps.p_stack[++ps.tos] = decl;
ps.il[ps.tos] = ps.i_l_follow;
if (ps.ljust_decl)
{ /* only do if we want left
justified declarations */
ps.ind_level = 0;
for (i = ps.tos - 1; i > 0; --i)
if (ps.p_stack[i] == decl)
++ps.ind_level; /* indentation is number of
declaration levels deep we
are */
ps.i_l_follow = ps.ind_level;
}
}
break;
case ifstmt: /* scanned if (...) */
if (ps.p_stack[ps.tos] == elsehead && ps.else_if) /* "else if ..." */
ps.i_l_follow = ps.il[ps.tos];
case dolit: /* 'do' */
case forstmt: /* for (...) */
ps.p_stack[++ps.tos] = tk;
ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
++ps.i_l_follow; /* subsequent statements should
be indented 1 */
ps.search_brace = btype_2;
break;
case lbrace: /* scanned { */
break_comma = false; /* don't break comma in an
initial list */
if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl
|| ps.p_stack[ps.tos] == stmtl)
++ps.i_l_follow; /* it is a random, isolated
stmt group or a declaration */
else
{
if (s_code == e_code)
{
/* only do this if there is nothing on the line */
--ps.ind_level;
/* it is a group as part of a while, for, etc. */
if (ps.p_stack[ps.tos] == swstmt && ps.case_indent >= 1)
--ps.ind_level;
/* for a switch, brace should be two levels out from the
code */
}
}
ps.p_stack[++ps.tos] = lbrace;
ps.il[ps.tos] = ps.ind_level;
ps.p_stack[++ps.tos] = stmt;
/* allow null stmt between braces */
ps.il[ps.tos] = ps.i_l_follow;
break;
case whilestmt: /* scanned while (...) */
if (ps.p_stack[ps.tos] == dohead)
{
/* it is matched with do stmt */
ps.ind_level = ps.i_l_follow = ps.il[ps.tos];
ps.p_stack[++ps.tos] = whilestmt;
ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
} else
{ /* it is a while loop */
ps.p_stack[++ps.tos] = whilestmt;
ps.il[ps.tos] = ps.i_l_follow;
++ps.i_l_follow;
ps.search_brace = btype_2;
}
break;
case elselit: /* scanned an else */
if (ps.p_stack[ps.tos] != ifhead)
diag(1, "Unmatched 'else'");
else
{
ps.ind_level = ps.il[ps.tos]; /* indentation for else should
be same as for if */
ps.i_l_follow = ps.ind_level + 1; /* everything following
should be in 1 level */
ps.p_stack[ps.tos] = elsehead;
/* remember if with else */
ps.search_brace = btype_2 | ps.else_if;
}
break;
case rbrace: /* scanned a } */
/* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */
if (ps.p_stack[ps.tos - 1] == lbrace)
{
ps.ind_level = ps.i_l_follow = ps.il[--ps.tos];
ps.p_stack[ps.tos] = stmt;
} else
diag(1, "Stmt nesting error.");
break;
case swstmt: /* had switch (...) */
ps.p_stack[++ps.tos] = swstmt;
ps.cstk[ps.tos] = case_ind;
/* save current case indent level */
ps.il[ps.tos] = ps.i_l_follow;
case_ind = ps.i_l_follow + ps.case_indent; /* cases should be one
level down from
switch */
ps.i_l_follow += ps.case_indent + 1; /* statements should be
two levels in */
ps.search_brace = btype_2;
break;
case semicolon: /* this indicates a simple stmt */
break_comma = false; /* turn off flag to break after
commas in a declaration */
ps.p_stack[++ps.tos] = stmt;
ps.il[ps.tos] = ps.ind_level;
break;
default: /* this is an error */
diag(1, "Unknown code to parser");
return;
} /* end of switch */
reduce(); /* see if any reduction can be
done */
#ifdef debug
for (i = 1; i <= ps.tos; ++i)
printf("(%d %d)", ps.p_stack[i], ps.il[i]);
printf("\n");
#endif
return;
}
/*
* Copyright (C) 1976 by the Board of Trustees of the University of Illinois
*
* All rights reserved
*
*
* NAME: reduce
*
* FUNCTION: Implements the reduce part of the parsing algorithm
*
* ALGORITHM: The following reductions are done. Reductions are repeated until
* no more are possible.
*
* Old TOS New TOS <stmt> <stmt> <stmtl> <stmtl> <stmt> <stmtl> do
* <stmt> "dostmt" if <stmt> "ifstmt" switch <stmt> <stmt> decl
* <stmt> <stmt> "ifelse" <stmt> <stmt> for <stmt> <stmt> while
* <stmt> <stmt> "dostmt" while <stmt>
*
* On each reduction, ps.i_l_follow (the indentation for the following line) is
* set to the indentation level associated with the old TOS.
*
* PARAMETERS: None
*
* RETURNS: Nothing
*
* GLOBALS: ps.cstk ps.i_l_follow = ps.il ps.p_stack = ps.tos =
*
* CALLS: None
*
* CALLED BY: parse
*
* HISTORY: initial coding November 1976 D A Willcox of CAC
*
*/
/*----------------------------------------------*\
| REDUCTION PHASE |
\*----------------------------------------------*/
void reduce()
{
register int i;
for (;;)
{ /* keep looping until there is
nothing left to reduce */
switch (ps.p_stack[ps.tos])
{
case stmt:
switch (ps.p_stack[ps.tos - 1])
{
case stmt:
case stmtl:
/* stmtl stmt or stmt stmt */
ps.p_stack[--ps.tos] = stmtl;
break;
case dolit: /* <do> <stmt> */
ps.p_stack[--ps.tos] = dohead;
ps.i_l_follow = ps.il[ps.tos];
break;
case ifstmt:
/* <if> <stmt> */
ps.p_stack[--ps.tos] = ifhead;
for (i = ps.tos - 1;
(
ps.p_stack[i] != stmt
&&
ps.p_stack[i] != stmtl
&&
ps.p_stack[i] != lbrace
);
--i);
ps.i_l_follow = ps.il[i];
/* for the time being, we will assume that there is no else
on this if, and set the indentation level accordingly.
If an else is scanned, it will be fixed up later */
break;
case swstmt:
/* <switch> <stmt> */
case_ind = ps.cstk[ps.tos - 1];
case decl: /* finish of a declaration */
case elsehead:
/* <<if> <stmt> else> <stmt> */
case forstmt:
/* <for> <stmt> */
case whilestmt:
/* <while> <stmt> */
ps.p_stack[--ps.tos] = stmt;
ps.i_l_follow = ps.il[ps.tos];
break;
default: /* <anything else> <stmt> */
return;
} /* end of section for <stmt> on
top of stack */
break;
case whilestmt: /* while (...) on top */
if (ps.p_stack[ps.tos - 1] == dohead)
{
/* it is termination of a do while */
ps.p_stack[--ps.tos] = stmt;
break;
} else
return;
default: /* anything else on top */
return;
}
}
}

View file

@ -1,26 +0,0 @@
/* _PROTOTYPE( void diag, (int level,char *msg, int a, int b) ); */
void diag(); /* HACK. should be varargs */
_PROTOTYPE( void set_profile, (void ) );
_PROTOTYPE( void scan_profile, (FILE *f) );
_PROTOTYPE( int eqin, (char *s1,char *s2) );
_PROTOTYPE( void set_defaults, (void ) );
_PROTOTYPE( void set_option, (char *arg) );
_PROTOTYPE( void pr_comment, (void ) );
_PROTOTYPE( int main, (int argc,char * *argv) );
_PROTOTYPE( void bakcopy, (void ) );
_PROTOTYPE( void dump_line, (void ) );
_PROTOTYPE( int code_target, (void ) );
_PROTOTYPE( int label_target, (void ) );
_PROTOTYPE( void fill_buffer, (void ) );
_PROTOTYPE( int pad_output, (int current,int target) );
_PROTOTYPE( int count_spaces, (int current,char *buffer) );
_PROTOTYPE( void writefdef, (struct fstate *f,int nm) );
_PROTOTYPE( char *chfont, (struct fstate *of,struct fstate *nf,char *s) );
_PROTOTYPE( void parsefont, (struct fstate *f,char *s0) );
_PROTOTYPE( int lexi, (void ) );
_PROTOTYPE( void addkey, (char *key,int val) );
_PROTOTYPE( void makext, (char *newname,char *newext) );
_PROTOTYPE( void parse, (int tk) );
_PROTOTYPE( void reduce, (void ) );

View file

@ -3,3 +3,4 @@ lib/nbsd_libc src/lib/libc
lib/nbsd_libm src/lib/libm
nbsd_include src/include
usr.bin/m4 src/usr.bin/m4
usr.bin/indent src/usr.bin/indent

View file

@ -2,6 +2,6 @@
.include <bsd.own.mk>
SUBDIR= m4 mkimage
SUBDIR= indent m4 mkimage
.include <bsd.subdir.mk>

7
usr.bin/indent/Makefile Normal file
View file

@ -0,0 +1,7 @@
# $NetBSD: Makefile,v 1.6 2006/10/08 17:52:28 peter Exp $
# from: @(#)Makefile 8.1 (Berkeley) 6/6/93
PROG= indent
SRCS= indent.c io.c lexi.c parse.c pr_comment.c args.c
.include <bsd.prog.mk>

97
usr.bin/indent/README Normal file
View file

@ -0,0 +1,97 @@
This is the C indenter, it originally came from the University of Illinois
via some distribution tape for PDP-11 Unix. It has subsequently been
hacked upon by James Gosling @ CMU. It isn't very pretty, and really needs
to be completely redone, but it is probably the nicest C pretty printer
around.
Further additions to provide "Kernel Normal Form" were contributed
by the folks at Sun Microsystems.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> From mnetor!yunexus!oz@uunet.UU.NET Wed Mar 9 15:30:55 1988
> Date: Tue, 8 Mar 88 18:36:25 EST
> From: yunexus!oz@uunet.UU.NET (Ozan Yigit)
> To: bostic@okeeffe.berkeley.edu
> Cc: ccvaxa!willcox@uunet.UU.NET, jag@sun.com, rsalz@uunet.UU.NET
> In-Reply-To: Keith Bostic's message of Tue, 16 Feb 88 16:09:06 PST
> Subject: Re: Indent...
Thank you for your response about indent. I was wrong in my original
observation (or mis-observation :-). UCB did keep the Illinois
copyright intact.
The issue still is whether we can distribute indent, and if we can, which
version. David Willcox (the author) states that:
| Several people have asked me on what basis I claim that indent is in
| the public domain. I knew I would be sorry I made that posting.
|
| Some history. Way back in 1976, the project I worked on at the
| University of Illinois Center for Advanced Computation had a huge
| battle about how to format C code. After about a week of fighting, I
| got disgusted and wrote a program, which I called indent, to reformat C
| code. It had a bunch of different options that would let you format
| the output the way you liked. In particular, all of the different
| formats being championed were supported.
|
| It was my first big C program. It was ugly. It wasn't designed, it
| just sort of grew. But it pretty much worked, and it stopped most of
| the fighting.
|
| As a matter of form, I included a University of Illinois Copyright
| notice. However, my understanding was that, since the work was done
| on an ARPA contract, it was in the public domain.
|
| Time passed. Some years later, indent showed up on one of the early
| emacs distributions.
|
| Later still, someone from UC Berlekey called the UofI and asked if
| indent was in the public domain. They wanted to include it in their
| UNIX distributions, along with the emacs stuff. I was no longer at the
| UofI, but Rob Kolstad, who was, asked me about it. I told him I didn't
| care if they used it, and since then it has been on the BSD distributions.
|
| Somewhere along the way, several other unnamed people have had their
| hands in it. It was converted to understand version 7 C. (The
| original was version 6.) It was converted from its original filter
| interface to its current "blow away the user's file" interface.
| The $HOME/.indent.pro file parsing was added. Some more formatting
| options were added.
|
| The source I have right now has two copyright notices. One is the
| original from the UofI. One is from Berkeley.
|
| I am not a lawyer, and I certainly do not understand copyright law. As
| far as I am concerned, the bulk of this program, everything covered by
| the UofI copyright, is in the public domain, and worth every penny.
| Berkeley's copyright probably should only cover their changes, and I
| don't know their feelings about sending it out.
In any case, there appears to be noone at UofI to clarify/and change
that copyright, but I am confident (based on the statements of its
author) that the code, as it stands with its copyright, is
distributable, and will not cause any legal problems.
Hence, the issue reduces to *which* one to distribute through
comp.sources.unix. I would suggest that with the permission of you
folks (given that you have parts copyrighted), we distribute the 4.3
version of indent, which appears to be the most up-to-date version. I
happen to have just about every known version of indent, including the
very original submission from the author to a unix tape, later the
G-Emacs version, any 4.n version, sun version and the Unipress
version. I still think we should not have to "go-back-in-time" and
re-do all the work you people have done.
I hope to hear from you as to what you think about this. You may of
course send 4.3 version to the moderator directly, or you can let me
know of your permission, and I will send the sources, or you can let
me know that 4.3 version is off-limits, in which case we would probably
have to revert to an older version. One way or another, I hope to get
a version of indent to comp.sources.unix.
regards.. oz
cc: ccvaxa!willcox
sun.com!jar
uunet!rsalz

461
usr.bin/indent/args.c Normal file
View file

@ -0,0 +1,461 @@
/* $NetBSD: args.c,v 1.10 2009/04/12 11:09:49 lukem Exp $ */
/*
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* Copyright (c) 1985 Sun Microsystems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)args.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: args.c,v 1.10 2009/04/12 11:09:49 lukem Exp $");
#endif
#endif /* not lint */
/*
* Argument scanning and profile reading code. Default parameters are set
* here as well.
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "indent_globs.h"
/* profile types */
#define PRO_SPECIAL 1 /* special case */
#define PRO_BOOL 2 /* boolean */
#define PRO_INT 3 /* integer */
#define PRO_FONT 4 /* troff font */
/* profile specials for booleans */
#define ON 1 /* turn it on */
#define OFF 0 /* turn it off */
/* profile specials for specials */
#define IGN 1 /* ignore it */
#define CLI 2 /* case label indent (float) */
#define STDIN 3 /* use stdin */
#define KEY 4 /* type (keyword) */
const char *option_source = "?";
/*
* N.B.: because of the way the table here is scanned, options whose names are
* substrings of other options must occur later; that is, with -lp vs -l, -lp
* must be first. Also, while (most) booleans occur more than once, the last
* default value is the one actually assigned.
*/
struct pro {
const char *p_name; /* name, eg -bl, -cli */
int p_type; /* type (int, bool, special) */
int p_default; /* the default value (if int) */
int p_special; /* depends on type */
int *p_obj; /* the associated variable */
} pro[] = {
{
"T", PRO_SPECIAL, 0, KEY, 0
},
{
"bacc", PRO_BOOL, false, ON, &blanklines_around_conditional_compilation
},
{
"badp", PRO_BOOL, false, ON, &blanklines_after_declarations_at_proctop
},
{
"bad", PRO_BOOL, false, ON, &blanklines_after_declarations
},
{
"bap", PRO_BOOL, false, ON, &blanklines_after_procs
},
{
"bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments
},
{
"bc", PRO_BOOL, true, OFF, &ps.leave_comma
},
{
"bl", PRO_BOOL, true, OFF, &btype_2
},
{
"br", PRO_BOOL, true, ON, &btype_2
},
{
"bs", PRO_BOOL, false, ON, &Bill_Shannon
},
{
"cdb", PRO_BOOL, true, ON, &comment_delimiter_on_blankline
},
{
"cd", PRO_INT, 0, 0, &ps.decl_com_ind
},
{
"ce", PRO_BOOL, true, ON, &cuddle_else
},
{
"ci", PRO_INT, 0, 0, &continuation_indent
},
{
"cli", PRO_SPECIAL, 0, CLI, 0
},
{
"c", PRO_INT, 33, 0, &ps.com_ind
},
{
"di", PRO_INT, 16, 0, &ps.decl_indent
},
{
"dj", PRO_BOOL, false, ON, &ps.ljust_decl
},
{
"d", PRO_INT, 0, 0, &ps.unindent_displace
},
{
"eei", PRO_BOOL, false, ON, &extra_expression_indent
},
{
"ei", PRO_BOOL, true, ON, &ps.else_if
},
{
"fbc", PRO_FONT, 0, 0, (int *) &blkcomf
},
{
"fbx", PRO_FONT, 0, 0, (int *) &boxcomf
},
{
"fb", PRO_FONT, 0, 0, (int *) &bodyf
},
{
"fc1", PRO_BOOL, true, ON, &format_col1_comments
},
{
"fc", PRO_FONT, 0, 0, (int *) &scomf
},
{
"fk", PRO_FONT, 0, 0, (int *) &keywordf
},
{
"fs", PRO_FONT, 0, 0, (int *) &stringf
},
{
"ip", PRO_BOOL, true, ON, &ps.indent_parameters
},
{
"i", PRO_INT, 8, 0, &ps.ind_size
},
{
"lc", PRO_INT, 0, 0, &block_comment_max_col
},
{
"lp", PRO_BOOL, true, ON, &lineup_to_parens
},
{
"l", PRO_INT, 78, 0, &max_col
},
{
"nbacc", PRO_BOOL, false, OFF, &blanklines_around_conditional_compilation
},
{
"nbadp", PRO_BOOL, false, OFF, &blanklines_after_declarations_at_proctop
},
{
"nbad", PRO_BOOL, false, OFF, &blanklines_after_declarations
},
{
"nbap", PRO_BOOL, false, OFF, &blanklines_after_procs
},
{
"nbbb", PRO_BOOL, false, OFF, &blanklines_before_blockcomments
},
{
"nbc", PRO_BOOL, true, ON, &ps.leave_comma
},
{
"nbs", PRO_BOOL, false, OFF, &Bill_Shannon
},
{
"ncdb", PRO_BOOL, true, OFF, &comment_delimiter_on_blankline
},
{
"nce", PRO_BOOL, true, OFF, &cuddle_else
},
{
"ndj", PRO_BOOL, false, OFF, &ps.ljust_decl
},
{
"neei", PRO_BOOL, false, OFF, &extra_expression_indent
},
{
"nei", PRO_BOOL, true, OFF, &ps.else_if
},
{
"nfc1", PRO_BOOL, true, OFF, &format_col1_comments
},
{
"nip", PRO_BOOL, true, OFF, &ps.indent_parameters
},
{
"nlp", PRO_BOOL, true, OFF, &lineup_to_parens
},
{
"npcs", PRO_BOOL, false, OFF, &proc_calls_space
},
{
"npro", PRO_SPECIAL, 0, IGN, 0
},
{
"npsl", PRO_BOOL, true, OFF, &procnames_start_line
},
{
"nps", PRO_BOOL, false, OFF, &pointer_as_binop
},
{
"nsc", PRO_BOOL, true, OFF, &star_comment_cont
},
{
"nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines
},
{
"nv", PRO_BOOL, false, OFF, &verbose
},
{
"pcs", PRO_BOOL, false, ON, &proc_calls_space
},
{
"psl", PRO_BOOL, true, ON, &procnames_start_line
},
{
"ps", PRO_BOOL, false, ON, &pointer_as_binop
},
{
"sc", PRO_BOOL, true, ON, &star_comment_cont
},
{
"sob", PRO_BOOL, false, ON, &swallow_optional_blanklines
},
{
"st", PRO_SPECIAL, 0, STDIN, 0
},
{
"troff", PRO_BOOL, false, ON, &troff
},
{
"v", PRO_BOOL, false, ON, &verbose
},
/* whew! */
{
0, 0, 0, 0, 0
}
};
/*
* set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments
* given in these files.
*/
void
set_profile(void)
{
FILE *f;
char fname[BUFSIZ];
static char prof[] = ".indent.pro";
snprintf(fname, sizeof(fname), "%s/%s", getenv("HOME"), prof);
if ((f = fopen(option_source = fname, "r")) != NULL) {
scan_profile(f);
(void) fclose(f);
}
if ((f = fopen(option_source = prof, "r")) != NULL) {
scan_profile(f);
(void) fclose(f);
}
option_source = "Command line";
}
void
scan_profile(FILE *f)
{
int i;
char *p;
char buf[BUFSIZ];
while (1) {
for (p = buf; (i = getc(f)) != EOF && (*p = i) > ' '; ++p);
if (p != buf) {
*p++ = 0;
if (verbose)
printf("profile: %s\n", buf);
set_option(buf);
} else
if (i == EOF)
return;
}
}
const char *param_start;
int
eqin(const char *s1, const char *s2)
{
while (*s1) {
if (*s1++ != *s2++)
return (false);
}
param_start = s2;
return (true);
}
/*
* Set the defaults.
*/
void
set_defaults(void)
{
struct pro *p;
/*
* Because ps.case_indent is a float, we can't initialize it from the
* table:
*/
ps.case_indent = 0.0; /* -cli0.0 */
for (p = pro; p->p_name; p++)
if (p->p_type != PRO_SPECIAL && p->p_type != PRO_FONT)
*p->p_obj = p->p_default;
}
void
set_option(char *arg)
{
struct pro *p;
arg++; /* ignore leading "-" */
for (p = pro; p->p_name; p++)
if (*p->p_name == *arg && eqin(p->p_name, arg))
goto found;
fprintf(stderr, "indent: %s: unknown parameter \"%s\"\n", option_source, arg - 1);
exit(1);
found:
switch (p->p_type) {
case PRO_SPECIAL:
switch (p->p_special) {
case IGN:
break;
case CLI:
if (*param_start == 0)
goto need_param;
ps.case_indent = atof(param_start);
break;
case STDIN:
if (input == 0)
input = stdin;
if (output == 0)
output = stdout;
break;
case KEY:
if (*param_start == 0)
goto need_param;
{
char *str;
str = strdup(param_start);
addkey(str, 4);
}
break;
default:
fprintf(stderr, "\
indent: set_option: internal error: p_special %d\n", p->p_special);
exit(1);
}
break;
case PRO_BOOL:
if (p->p_special == OFF)
*p->p_obj = false;
else
*p->p_obj = true;
break;
case PRO_INT:
if (!isdigit((unsigned char)*param_start)) {
need_param:
fprintf(stderr, "indent: %s: ``%s'' requires a parameter\n",
option_source, arg - 1);
exit(1);
}
*p->p_obj = atoi(param_start);
break;
case PRO_FONT:
parsefont((struct fstate *) p->p_obj, param_start);
break;
default:
fprintf(stderr, "indent: set_option: internal error: p_type %d\n",
p->p_type);
exit(1);
}
}

562
usr.bin/indent/indent.1 Normal file
View file

@ -0,0 +1,562 @@
.\" $NetBSD: indent.1,v 1.20 2011/01/12 06:17:52 wiz Exp $
.\"
.\" Copyright (c) 1980, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" Copyright (c) 1985 Sun Microsystems, Inc.
.\" Copyright (c) 1976 Board of Trustees of the University of Illinois.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" from: @(#)indent.1 8.1 (Berkeley) 7/1/93
.\"
.Dd July 1, 1993
.Dt INDENT 1
.Os
.Sh NAME
.Nm indent
.Nd indent and format C program source
.Sh SYNOPSIS
.Nm
.Bk -words
.Op Ar input-file Op Ar output-file
.Ek
.Bk -words
.Op Fl bacc | Fl nbacc
.Ek
.Bk -words
.Op Fl bad | Fl nbad
.Ek
.Bk -words
.Op Fl bap | Fl nbap
.Ek
.Bk -words
.Op Fl bbb | Fl nbbb
.Ek
.Bk -words
.Op Fl \&bc | Fl nbc
.Ek
.Op Fl \&bl
.Op Fl \&br
.Op Fl c Ns Ar n
.Op Fl \&cd Ns Ar n
.Bk -words
.Op Fl cdb | Fl ncdb
.Ek
.Bk -words
.Op Fl \&ce | Fl nce
.Ek
.Op Fl \&ci Ns Ar n
.Op Fl cli Ns Ar n
.Op Fl d Ns Ar n
.Op Fl \&di Ns Ar n
.Bk -words
.Op Fl fc1 | Fl nfc1
.Ek
.Op Fl i Ns Ar n
.Bk -words
.Op Fl \&ip | Fl nip
.Ek
.Op Fl l Ns Ar n
.Op Fl \&lc Ns Ar n
.Bk -words
.Op Fl \&lp | Fl nlp
.Ek
.Op Fl npro
.Bk -words
.Op Fl pcs | Fl npcs
.Ek
.Bk -words
.Op Fl psl | Fl npsl
.Ek
.Bk -words
.Op Fl \&sc | Fl nsc
.Ek
.Bk -words
.Op Fl sob | Fl nsob
.Ek
.Op Fl \&st
.Op Fl troff
.Bk -words
.Op Fl v | Fl \&nv
.Ek
.Sh DESCRIPTION
.Nm
is a
.Tn C
program formatter.
It reformats the
.Tn C
program in the
.Ar input-file
according to the switches.
The switches which can be specified are described below.
They may appear before or after the file names.
.Pp
.Sy NOTE :
If you only specify an
.Ar input-file ,
the formatting is
done `in-place', that is, the formatted file is written back into
.Ar input-file
and a backup copy of
.Ar input-file
is written in the current directory.
If
.Ar input-file
is named
.Sq Pa /blah/blah/file ,
the backup file is named
.Pa file.BAK .
.Pp
If
.Ar output-file
is specified,
.Nm
checks to make sure it is different from
.Ar input-file .
.Pp
The options listed below control the formatting style imposed by
.Nm .
.Bl -tag -width Op
.It Fl bacc , nbacc
If
.Fl bacc
is specified, a blank line is forced around every conditional
compilation block.
For example, in front of every #ifdef and after every #endif.
Other blank lines surrounding such blocks will be swallowed.
Default:
.Fl nbacc .
.It Fl bad , nbad
If
.Fl bad
is specified, a blank line is forced after every block of
declarations.
Default:
.Fl nbad .
.It Fl bap , nbap
If
.Fl bap
is specified, a blank line is forced after every procedure body.
Default:
.Fl nbap .
.It Fl bbb , nbbb
If
.Fl bbb
is specified, a blank line is forced before every block comment.
Default:
.Fl nbbb .
.It Fl \&bc , nbc
If
.Fl \&bc
is specified, then a newline is forced after each comma in a declaration.
.Fl nbc
turns off this option.
Default:
.Fl \&bc .
.It Fl \&br , \&bl
Specifying
.Fl \&bl
lines up compound statements like this:
.Bd -literal -offset indent
if (...)
{
code
}
.Ed
.Pp
Specifying
.Fl \&br
(the default) makes them look like this:
.Bd -literal -offset indent
if (...) {
code
}
.Ed
.Pp
.It Fl bs , Fl nbs
If
.Fl bs
is specified, a blank is forced after
.Ic sizeof .
Default:
.Fl nbs .
.It Fl c Ns Ar n
The column in which comments on code start.
Default:
.Fl c33 .
.It Fl cd Ns Ar n
The column in which comments on declarations start.
The default
is for these comments to start in the same column as those on code.
.It Fl cdb , ncdb
Enables (disables) the placement of comment delimiters on blank lines.
With this option enabled, comments look like this:
.Bd -literal -offset indent
/*
* this is a comment
*/
.Ed
.Pp
Rather than like this:
.Bd -literal -offset indent
/* this is a comment */
.Ed
.Pp
This only affects block comments, not comments to the right of
code.
Default:
.Fl cdb .
.It Fl ce , nce
Enables (disables) forcing `else's to cuddle up to the immediately preceding
`}'.
Default:
.Fl \&ce .
.It Fl \&ci Ns Ar n
Sets the continuation indent to be
.Ar n .
Continuation
lines will be indented that far from the beginning of the first line of the
statement.
Parenthesized expressions have extra indentation added to
indicate the nesting, unless
.Fl \&lp
is in effect.
.Fl \&ci
defaults to the same value as
.Fl i .
.It Fl cli Ns Ar n
Causes case labels to be indented
.Ar n
tab stops to the right of the containing
.Ic switch
statement.
.Fl cli0.5
causes case labels to be indented half a tab stop.
Default:
.Fl cli0 .
.It Fl d Ns Ar n
Controls the placement of comments which are not to the right of code.
For example,
.Fl \&d\&1
means that such comments are placed one indentation level to the left of code.
Specifying the default
.Fl \&d\&0
lines up these comments with the code.
See the section on comment
indentation below.
.It Fl \&di Ns Ar n
Specifies the indentation, in character positions, from a declaration keyword
to the following identifier.
Default:
.Fl di16 .
.It Fl dj , ndj
.Fl \&dj
left justifies declarations.
.Fl ndj
indents declarations the same as code.
Default:
.Fl ndj .
.It Fl \&ei , nei
Enables (disables) special
.Ic else-if
processing.
If it's enabled, an
.Ic if
following an
.Ic else
will have the same indentation as the preceding
.Ic \&if
statement.
Default:
.Fl ei .
.It Fl eei , neei
Enables (disables) extra indentation on continuation lines of
the expression part of
.Ic if
and
.Ic while
statements.
These continuation lines will be indented one extra level.
Default:
.Fl neei .
.It Fl fc1 , nfc1
Enables (disables) the formatting of comments that start in column 1.
Often, comments whose leading `/' is in column 1 have been carefully
hand formatted by the programmer.
In such cases,
.Fl nfc1
should be used.
Default:
.Fl fc1 .
.It Fl i Ns Ar n
The number of spaces for one indentation level.
Default:
.Fl i8 .
.It Fl \&ip , nip
Enables (disables) the indentation of parameter declarations from the left
margin.
Default:
.Fl \&ip .
.It Fl l Ns Ar n
Maximum length of an output line.
Default:
.Fl l78 .
.It Fl \&lp , nlp
Lines up code surrounded by parenthesis in continuation lines.
If a line has a left parenthesis which is not closed on that line, then
continuation lines will be lined up to start at the character
position just after the left parenthesis.
For example, here is how a piece of continued code looks with
.Fl nlp
in effect:
.Bd -literal -offset indent
p1 = first_procedure(second_procedure(p2, p3),
\ \ third_procedure(p4,p5));
.Ed
.Pp
With
.Fl lp
in effect (the default) the code looks somewhat clearer:
.Bd -literal -offset indent
p1\ =\ first_procedure(second_procedure(p2,\ p3),
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ third_procedure(p4,p5));
.Ed
.Pp
Inserting two more newlines we get:
.Bd -literal -offset indent
p1\ =\ first_procedure(second_procedure(p2,
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ p3),
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ third_procedure(p4
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ p5));
.Ed
.It Fl npro
Causes the profile files,
.Sq Pa ./.indent.pro
and
.Sq Pa ~/.indent.pro ,
to be ignored.
.It Fl pcs , npcs
If true
.Pq Fl pcs
all procedure calls will have a space inserted between
the name and the `('.
Default:
.Fl npcs .
.It Fl psl , npsl
If true
.Pq Fl psl
the names of procedures being defined are placed in
column 1 \- their types, if any, will be left on the previous lines.
Default:
.Fl psl .
.It Fl \&sc , nsc
Enables (disables) the placement of asterisks (`*'s) at the left edge of all
comments.
Default:
.Fl sc .
.It Fl sob , nsob
If
.Fl sob
is specified, indent will swallow optional blank lines.
You can use this to get rid of blank lines after declarations.
Default:
.Fl nsob .
.It Fl \&st
Causes
.Nm
to take its input from stdin, and put its output to stdout.
.It Fl T Ns Ar typename
Adds
.Ar typename
to the list of type keywords.
Names accumulate:
.Fl T
can be specified more than once.
You need to specify all the typenames that
appear in your program that are defined by
.Ic typedef
\- nothing will be
harmed if you miss a few, but the program won't be formatted as nicely as
it should.
This sounds like a painful thing to have to do, but it's really
a symptom of a problem in C:
.Ic typedef
causes a syntactic change in the
language and
.Nm
can't find all
instances of
.Ic typedef .
.It Fl troff
Causes
.Nm
to format the program for processing by
.Xr troff 1 .
It will produce a fancy
listing in much the same spirit as
.Xr vgrind 1 .
If the output file is not specified, the default is standard output,
rather than formatting in place.
.It Fl v , \&nv
.Fl v
turns on `verbose' mode;
.Fl \&nv
turns it off.
When in verbose mode,
.Nm
reports when it splits one line of input into two or more lines of output,
and gives some size statistics at completion.
Default:
.Fl \&nv .
.El
.Pp
You may set up your own `profile' of defaults to
.Nm
by creating a file called
.Pa .indent.pro
in your login directory and/or the current directory and including
whatever switches you like.
A `.indent.pro' in the current directory takes
precedence over the one in your login directory.
If
.Nm
is run and a profile file exists, then it is read to set up the program's
defaults.
Switches on the command line, though, always override profile switches.
The switches should be separated by spaces, tabs or newlines.
.Ss Comments
.Sq Em Box
.Em comments .
.Nm
assumes that any comment with a dash or star immediately after the start of
comment (that is, `/*\-' or `/**') is a comment surrounded by a box of stars.
Each line of such a comment is left unchanged, except that its indentation
may be adjusted to account for the change in indentation of the first line
of the comment.
.Pp
.Em Straight text .
All other comments are treated as straight text.
.Nm
fits as many words (separated by blanks, tabs, or newlines) on a
line as possible.
Blank lines break paragraphs.
.Ss Comment indentation
If a comment is on a line with code it is started in the `comment column',
which is set by the
.Fl c Ns Ns Ar n
command line parameter.
Otherwise, the comment is started at
.Ar n
indentation levels less than where code is currently being placed, where
.Ar n
is specified by the
.Fl d Ns Ns Ar n
command line parameter.
If the code on a line extends past the comment
column, the comment starts further to the right, and the right margin may be
automatically extended in extreme cases.
.Ss Preprocessor lines
In general,
.Nm
leaves preprocessor lines alone.
The only reformatting that it will do is to straighten up trailing comments.
It leaves embedded comments alone.
Conditional compilation
.Pq Ic #ifdef...#endif
is recognized and
.Nm
attempts to correctly
compensate for the syntactic peculiarities introduced.
.Ss C syntax
.Nm
understands a substantial amount about the syntax of C, but it
has a `forgiving' parser.
It attempts to cope with the usual sorts of incomplete and misformed syntax.
In particular, the use of macros like:
.Pp
.Dl #define forever for(;;)
.Pp
is handled properly.
.Sh ENVIRONMENT
.Nm
uses the
.Ev HOME
environment variable.
.Sh FILES
.Bl -tag -width "./.indent.pro" -compact
.It Pa ./.indent.pro
profile file
.It Pa ~/.indent.pro
profile file
.El
.Sh HISTORY
The
.Nm
command appeared in
.Bx 4.2 .
.Sh BUGS
.Nm
has even more switches than
.Xr ls 1 .
.Pp
A common mistake that often causes grief is typing:
.Pp
.Dl indent *.c
.Pp
to the shell in an attempt to indent all the
.Tn C
programs in a directory.
This is probably a bug, not a feature.

1281
usr.bin/indent/indent.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,101 @@
/* $NetBSD: indent_codes.h,v 1.5 2003/08/07 11:14:08 agc Exp $ */
/*
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)indent_codes.h 8.1 (Berkeley) 6/6/93
*/
/*
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)indent_codes.h 8.1 (Berkeley) 6/6/93
*/
#define newline 1
#define lparen 2
#define rparen 3
#define unary_op 4
#define binary_op 5
#define postop 6
#define question 7
#define casestmt 8
#define colon 9
#define semicolon 10
#define lbrace 11
#define rbrace 12
#define ident 13
#define comma 14
#define comment 15
#define swstmt 16
#define preesc 17
#define form_feed 18
#define decl 19
#define sp_paren 20
#define sp_nparen 21
#define ifstmt 22
#define whilestmt 23
#define forstmt 24
#define stmt 25
#define stmtl 26
#define elselit 27
#define dolit 28
#define dohead 29
#define ifhead 30
#define elsehead 31
#define period 32

View file

@ -0,0 +1,363 @@
/* $NetBSD: indent_globs.h,v 1.9 2009/04/12 11:09:49 lukem Exp $ */
/*
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)indent_globs.h 8.1 (Berkeley) 6/6/93
*/
/*
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)indent_globs.h 8.1 (Berkeley) 6/6/93
*/
#define BACKSLASH '\\'
#define bufsize 200 /* size of internal buffers */
#define sc_size 5000 /* size of save_com buffer */
#define label_offset 2 /* number of levels a label is placed to left
* of code */
#define tabsize 8 /* the size of a tab */
#define tabmask 0177770 /* mask used when figuring length of lines
* with tabs */
#define false 0
#define true 1
#ifndef EXTERN
#define EXTERN extern
#endif
EXTERN FILE *input; /* the fid for the input file */
EXTERN FILE *output; /* the output file */
#define CHECK_SIZE_CODE \
if (e_code >= l_code) { \
int nsize = l_code-s_code+400; \
codebuf = (char *) realloc(codebuf, nsize); \
e_code = codebuf + (e_code-s_code) + 1; \
l_code = codebuf + nsize - 5; \
s_code = codebuf + 1; \
}
#define CHECK_SIZE_COM \
if (e_com >= l_com) { \
int nsize = l_com-s_com+400; \
combuf = (char *) realloc(combuf, nsize); \
e_com = combuf + (e_com-s_com) + 1; \
l_com = combuf + nsize - 5; \
s_com = combuf + 1; \
}
#define CHECK_SIZE_LAB \
if (e_lab >= l_lab) { \
int nsize = l_lab-s_lab+400; \
labbuf = (char *) realloc(labbuf, nsize); \
e_lab = labbuf + (e_lab-s_lab) + 1; \
l_lab = labbuf + nsize - 5; \
s_lab = labbuf + 1; \
}
#define CHECK_SIZE_TOKEN \
if (e_token >= l_token) { \
int nsize = l_token-s_token+400; \
tokenbuf = (char *) realloc(tokenbuf, nsize); \
e_token = tokenbuf + (e_token-s_token) + 1; \
l_token = tokenbuf + nsize - 5; \
s_token = tokenbuf + 1; \
}
EXTERN char *labbuf; /* buffer for label */
EXTERN char *s_lab; /* start ... */
EXTERN char *e_lab; /* .. and end of stored label */
EXTERN char *l_lab; /* limit of label buffer */
EXTERN char *codebuf; /* buffer for code section */
EXTERN char *s_code; /* start ... */
EXTERN char *e_code; /* .. and end of stored code */
EXTERN char *l_code; /* limit of code section */
EXTERN char *combuf; /* buffer for comments */
EXTERN char *s_com; /* start ... */
EXTERN char *e_com; /* ... and end of stored comments */
EXTERN char *l_com; /* limit of comment buffer */
#define token s_token
EXTERN char *tokenbuf; /* the last token scanned */
EXTERN char *s_token;
EXTERN char *e_token;
EXTERN char *l_token;
EXTERN char *in_buffer; /* input buffer */
EXTERN char *in_buffer_limit; /* the end of the input buffer */
EXTERN char *buf_ptr; /* ptr to next character to be taken from
* in_buffer */
EXTERN char *buf_end; /* ptr to first after last char in in_buffer */
EXTERN char save_com[sc_size]; /* input text is saved here when looking for
* the brace after an if, while, etc */
EXTERN char *sc_end; /* pointer into save_com buffer */
EXTERN char *bp_save; /* saved value of buf_ptr when taking input
* from save_com */
EXTERN char *be_save; /* similarly saved value of buf_end */
EXTERN int pointer_as_binop;
EXTERN int blanklines_after_declarations;
EXTERN int blanklines_before_blockcomments;
EXTERN int blanklines_after_procs;
EXTERN int blanklines_around_conditional_compilation;
EXTERN int swallow_optional_blanklines;
EXTERN int n_real_blanklines;
EXTERN int prefix_blankline_requested;
EXTERN int postfix_blankline_requested;
EXTERN int break_comma; /* when true and not in parens, break after a
* comma */
EXTERN int btype_2; /* when true, brace should be on same line as
* if, while, etc */
EXTERN float case_ind; /* indentation level to be used for a "case
* n:" */
EXTERN int code_lines; /* count of lines with code */
EXTERN int had_eof; /* set to true when input is exhausted */
EXTERN int line_no; /* the current line number. */
EXTERN int max_col; /* the maximum allowable line length */
EXTERN int verbose; /* when true, non-essential error messages are
* printed */
EXTERN int cuddle_else; /* true if else should cuddle up to '}' */
EXTERN int star_comment_cont; /* true iff comment continuation lines should
* have stars at the beginning of each line. */
EXTERN int comment_delimiter_on_blankline;
EXTERN int troff; /* true iff were generating troff input */
EXTERN int procnames_start_line; /* if true, the names of procedures being
* defined get placed in column 1 (ie. a
* newline is placed between the type of the
* procedure and its name) */
EXTERN int proc_calls_space; /* If true, procedure calls look like:
* foo(bar) rather than foo (bar) */
EXTERN int format_col1_comments; /* If comments which start in column 1 are to
* be magically reformatted (just like
* comments that begin in later columns) */
EXTERN int inhibit_formatting; /* true if INDENT OFF is in effect */
EXTERN int suppress_blanklines; /* set iff following blanklines should be
* suppressed */
EXTERN int continuation_indent; /* set to the indentation between the edge of
* code and continuation lines */
EXTERN int lineup_to_parens; /* if true, continued code within parens will
* be lined up to the open paren */
EXTERN int Bill_Shannon; /* true iff a blank should always be inserted
* after sizeof */
EXTERN int blanklines_after_declarations_at_proctop; /* This is vaguely
* similar to
* blanklines_after_decla
* rations except that
* it only applies to
* the first set of
* declarations in a
* procedure (just after
* the first '{') and it
* causes a blank line
* to be generated even
* if there are no
* declarations */
EXTERN int block_comment_max_col;
EXTERN int extra_expression_indent; /* True if continuation lines from the
* expression part of "if(e)", "while(e)",
* "for(e;e;e)" should be indented an extra
* tab stop so that they don't conflict with
* the code that follows */
/* -troff font state information */
struct fstate {
char font[4];
char size;
int allcaps:1;
};
EXTERN struct fstate
keywordf, /* keyword font */
stringf, /* string font */
boxcomf, /* Box comment font */
blkcomf, /* Block comment font */
scomf, /* Same line comment font */
bodyf; /* major body font */
#define STACK_SIZE 150
EXTERN struct parser_state {
int last_token;
struct fstate cfont; /* Current font */
int p_stack[STACK_SIZE]; /* this is the parsers stack */
int il[STACK_SIZE]; /* this stack stores indentation levels */
float cstk[STACK_SIZE];/* used to store case stmt indentation levels */
int box_com; /* set to true when we are in a "boxed"
* comment. In that case, the first non-blank
* char should be lined up with the comment / */
int comment_delta, n_comment_delta;
int cast_mask; /* indicates which close parens close off
* casts */
int sizeof_mask; /* indicates which close parens close off
* sizeof''s */
int block_init; /* true iff inside a block initialization */
int block_init_level; /* The level of brace nesting in an
* initialization */
int last_nl; /* this is true if the last thing scanned was
* a newline */
int in_or_st; /* Will be true iff there has been a
* declarator (e.g. int or char) and no left
* paren since the last semicolon. When true,
* a '{' is starting a structure definition or
* an initialization list */
int bl_line; /* set to 1 by dump_line if the line is blank */
int col_1; /* set to true if the last token started in
* column 1 */
int com_col; /* this is the column in which the current
* coment should start */
int com_ind; /* the column in which comments to the right
* of code should start */
int com_lines; /* the number of lines with comments, set by
* dump_line */
int dec_nest; /* current nesting level for structure or init */
int decl_com_ind; /* the column in which comments after
* declarations should be put */
int decl_on_line; /* set to true if this line of code has part
* of a declaration on it */
int i_l_follow; /* the level to which ind_level should be set
* after the current line is printed */
int in_decl; /* set to true when we are in a declaration
* stmt. The processing of braces is then
* slightly different */
int in_stmt; /* set to 1 while in a stmt */
int ind_level; /* the current indentation level */
int ind_size; /* the size of one indentation level */
int ind_stmt; /* set to 1 if next line should have an extra
* indentation level because we are in the
* middle of a stmt */
int last_u_d; /* set to true after scanning a token which
* forces a following operator to be unary */
int leave_comma; /* if true, never break declarations after
* commas */
int ljust_decl; /* true if declarations should be left
* justified */
int out_coms; /* the number of comments processed, set by
* pr_comment */
int out_lines; /* the number of lines written, set by
* dump_line */
int p_l_follow; /* used to remember how to indent following
* statement */
int paren_level; /* parenthesization level. used to indent
* within stmts */
short paren_indents[20]; /* column positions of each paren */
int pcase; /* set to 1 if the current line label is a
* case. It is printed differently from a
* regular label */
int search_brace; /* set to true by parse when it is necessary
* to buffer up all info up to the start of a
* stmt after an if, while, etc */
int unindent_displace; /* comments not to the right of code
* will be placed this many
* indentation levels to the left of
* code */
int use_ff; /* set to one if the current line should be
* terminated with a form feed */
int want_blank; /* set to true when the following token should
* be prefixed by a blank. (Said prefixing is
* ignored in some cases.) */
int else_if; /* True iff else if pairs should be handled
* specially */
int decl_indent; /* column to indent declared identifiers to */
int its_a_keyword;
int sizeof_keyword;
int dumped_decl_indent;
float case_indent; /* The distance to indent case labels from the
* switch statement */
int in_parameter_declaration;
int indent_parameters;
int tos; /* pointer to top of stack */
char procname[100]; /* The name of the current procedure */
int just_saw_decl;
} ps;
EXTERN int ifdef_level;
EXTERN int rparen_count;
EXTERN struct parser_state state_stack[5];
EXTERN struct parser_state match_state[5];
int compute_code_target(void);
int compute_label_target(void);
int count_spaces(int, char *);
void diag(int, const char *,...) __attribute__((__format__(__printf__, 2, 3)));
void dump_line(void);
int eqin(const char *, const char *);
void fill_buffer(void);
int pad_output(int, int);
void scan_profile(FILE *);
void set_defaults(void);
void set_option(char *);
void addkey(char *, int);
void set_profile(void);
char *chfont(struct fstate *, struct fstate *, char *);
void parsefont(struct fstate *, const char *);
void writefdef(struct fstate *, int);
int lexi(void);
void reduce(void);
void parse(int);
void pr_comment(void);
void bakcopy(void);

685
usr.bin/indent/io.c Normal file
View file

@ -0,0 +1,685 @@
/* $NetBSD: io.c,v 1.14 2009/04/12 11:09:49 lukem Exp $ */
/*
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* Copyright (c) 1985 Sun Microsystems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)io.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: io.c,v 1.14 2009/04/12 11:09:49 lukem Exp $");
#endif
#endif /* not lint */
#include <ctype.h>
#include <err.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "indent_globs.h"
int comment_open;
static int paren_target;
void
dump_line(void)
{ /* dump_line is the routine that actually
* effects the printing of the new source. It
* prints the label section, followed by the
* code section with the appropriate nesting
* level, followed by any comments */
int cur_col, target_col;
static int not_first_line;
target_col = 0;
if (ps.procname[0]) {
if (troff) {
if (comment_open) {
comment_open = 0;
fprintf(output, ".*/\n");
}
fprintf(output, ".Pr \"%s\"\n", ps.procname);
}
ps.ind_level = 0;
ps.procname[0] = 0;
}
if (s_code == e_code && s_lab == e_lab && s_com == e_com) {
if (suppress_blanklines > 0)
suppress_blanklines--;
else {
ps.bl_line = true;
n_real_blanklines++;
}
} else
if (!inhibit_formatting) {
suppress_blanklines = 0;
ps.bl_line = false;
if (prefix_blankline_requested && not_first_line) {
if (swallow_optional_blanklines) {
if (n_real_blanklines == 1)
n_real_blanklines = 0;
} else {
if (n_real_blanklines == 0)
n_real_blanklines = 1;
}
}
while (--n_real_blanklines >= 0)
putc('\n', output);
n_real_blanklines = 0;
if (ps.ind_level == 0)
ps.ind_stmt = 0; /* this is a class A
* kludge. dont do
* additional statement
* indentation if we are
* at bracket level 0 */
if (e_lab != s_lab || e_code != s_code)
++code_lines; /* keep count of lines with
* code */
if (e_lab != s_lab) { /* print lab, if any */
if (comment_open) {
comment_open = 0;
fprintf(output, ".*/\n");
}
while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
e_lab--;
cur_col = pad_output(1, compute_label_target());
if (s_lab[0] == '#' && (strncmp(s_lab, "#else", 5) == 0
|| strncmp(s_lab, "#endif", 6) == 0)) {
char *s = s_lab;
if (e_lab[-1] == '\n')
e_lab--;
do
putc(*s++, output);
while (s < e_lab && 'a' <= *s && *s <= 'z');
while ((*s == ' ' || *s == '\t') && s < e_lab)
s++;
if (s < e_lab)
fprintf(output, s[0] == '/' && s[1] == '*' ? "\t%.*s" : "\t/* %.*s */",
(int)(e_lab - s), s);
} else
fprintf(output, "%.*s", (int)(e_lab - s_lab), s_lab);
cur_col = count_spaces(cur_col, s_lab);
} else
cur_col = 1; /* there is no label section */
ps.pcase = false;
if (s_code != e_code) { /* print code section, if any */
char *p;
if (comment_open) {
comment_open = 0;
fprintf(output, ".*/\n");
}
target_col = compute_code_target();
{
int i;
for (i = 0; i < ps.p_l_follow; i++)
if (ps.paren_indents[i] >= 0)
ps.paren_indents[i] = -(ps.paren_indents[i] + target_col);
}
cur_col = pad_output(cur_col, target_col);
for (p = s_code; p < e_code; p++)
if (*p == (char) 0200)
fprintf(output, "%d", target_col * 7);
else
putc(*p, output);
cur_col = count_spaces(cur_col, s_code);
}
if (s_com != e_com) {
if (troff) {
int all_here = 0;
char *p;
if (e_com[-1] == '/' && e_com[-2] == '*')
e_com -= 2, all_here++;
while (e_com > s_com && e_com[-1] == ' ')
e_com--;
*e_com = 0;
p = s_com;
while (*p == ' ')
p++;
if (p[0] == '/' && p[1] == '*')
p += 2, all_here++;
else
if (p[0] == '*')
p += p[1] == '/' ? 2 : 1;
while (*p == ' ')
p++;
if (*p == 0)
goto inhibit_newline;
if (comment_open < 2 && ps.box_com) {
comment_open = 0;
fprintf(output, ".*/\n");
}
if (comment_open == 0) {
if ('a' <= *p && *p <= 'z')
*p = *p + 'A' - 'a';
if (e_com - p < 50 && all_here == 2) {
char *follow = p;
fprintf(output, "\n.nr C! \\w\1");
while (follow < e_com) {
switch (*follow) {
case '\n':
putc(' ', output);
case 1:
break;
case '\\':
putc('\\', output);
default:
putc(*follow, output);
}
follow++;
}
putc(1, output);
}
fprintf(output, "\n./* %dp %d %dp\n",
ps.com_col * 7,
(s_code != e_code || s_lab != e_lab) - ps.box_com,
target_col * 7);
}
comment_open = 1 + ps.box_com;
while (*p) {
if (*p == BACKSLASH)
putc(BACKSLASH, output);
putc(*p++, output);
}
} else { /* print comment, if any */
int target = ps.com_col;
char *com_st = s_com;
target += ps.comment_delta;
while (*com_st == '\t')
com_st++, target += 8; /* ? */
while (target <= 0)
if (*com_st == ' ')
target++, com_st++;
else
if (*com_st == '\t')
target = ((target - 1) & ~7) + 9, com_st++;
else
target = 1;
if (cur_col > target) { /* if comment cant fit
* on this line, put it
* on next line */
putc('\n', output);
cur_col = 1;
++ps.out_lines;
}
while (e_com > com_st
&& isspace((unsigned char)e_com[-1]))
e_com--;
cur_col = pad_output(cur_col, target);
if (!ps.box_com) {
if (star_comment_cont
&& (com_st[1] != '*'
|| e_com <= com_st + 1)) {
if (com_st[1] == ' '
&& com_st[0] == ' '
&& e_com > com_st + 1)
com_st[1] = '*';
else
fwrite(" * ",
com_st[0] == '\t'
? 2
: com_st[0]=='*'
? 1
: 3, 1, output);
}
}
fwrite(com_st,
e_com - com_st, 1, output);
ps.comment_delta = ps.n_comment_delta;
cur_col = count_spaces(cur_col, com_st);
++ps.com_lines; /* count lines with
* comments */
}
}
if (ps.use_ff)
putc('\014', output);
else
putc('\n', output);
inhibit_newline:
++ps.out_lines;
if (ps.just_saw_decl == 1 && blanklines_after_declarations) {
prefix_blankline_requested = 1;
ps.just_saw_decl = 0;
} else
prefix_blankline_requested = postfix_blankline_requested;
postfix_blankline_requested = 0;
}
ps.decl_on_line = ps.in_decl; /* if we are in the middle of a
* declaration, remember that fact for
* proper comment indentation */
ps.ind_stmt = ps.in_stmt & ~ps.in_decl; /* next line should be
* indented if we have not
* completed this stmt and if
* we are not in the middle of
* a declaration */
ps.use_ff = false;
ps.dumped_decl_indent = 0;
*(e_lab = s_lab) = '\0';/* reset buffers */
*(e_code = s_code) = '\0';
*(e_com = s_com) = '\0';
ps.ind_level = ps.i_l_follow;
ps.paren_level = ps.p_l_follow;
paren_target = -ps.paren_indents[ps.paren_level - 1];
not_first_line = 1;
}
int
compute_code_target(void)
{
int target_col = ps.ind_size * ps.ind_level + 1;
if (ps.paren_level) {
if (!lineup_to_parens)
target_col += continuation_indent * ps.paren_level;
else {
int w;
int t = paren_target;
if ((w = count_spaces(t, s_code) - max_col) > 0
&& count_spaces(target_col, s_code) <= max_col) {
t -= w + 1;
if (t > target_col)
target_col = t;
} else
target_col = t;
}
} else
if (ps.ind_stmt)
target_col += continuation_indent;
return target_col;
}
int
compute_label_target(void)
{
return
ps.pcase ? (int) (case_ind * ps.ind_size) + 1
: *s_lab == '#' ? 1
: ps.ind_size * (ps.ind_level - label_offset) + 1;
}
/*
* Copyright (C) 1976 by the Board of Trustees of the University of Illinois
*
* All rights reserved
*
*
* NAME: fill_buffer
*
* FUNCTION: Reads one block of input into input_buffer
*
* HISTORY: initial coding November 1976 D A Willcox of CAC 1/7/77 A
* Willcox of CAC Added check for switch back to partly full input
* buffer from temporary buffer
*
*/
void
fill_buffer(void)
{ /* this routine reads stuff from the input */
char *p;
int i;
FILE *f = input;
char *n;
if (bp_save != 0) { /* there is a partly filled input buffer left */
buf_ptr = bp_save; /* dont read anything, just switch
* buffers */
buf_end = be_save;
bp_save = be_save = 0;
if (buf_ptr < buf_end)
return; /* only return if there is really something in
* this buffer */
}
for (p = in_buffer;;) {
if (p >= in_buffer_limit) {
int size = (in_buffer_limit - in_buffer) * 2 + 10;
int offset = p - in_buffer;
n = (char *) realloc(in_buffer, size);
if (n == 0)
errx(1, "input line too long");
in_buffer = n;
p = in_buffer + offset;
in_buffer_limit = in_buffer + size - 2;
}
if ((i = getc(f)) == EOF) {
*p++ = ' ';
*p++ = '\n';
had_eof = true;
break;
}
*p++ = i;
if (i == '\n')
break;
}
buf_ptr = in_buffer;
buf_end = p;
if (p[-2] == '/' && p[-3] == '*') {
if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0)
fill_buffer(); /* flush indent error message */
else {
int com = 0;
p = in_buffer;
while (*p == ' ' || *p == '\t')
p++;
if (*p == '/' && p[1] == '*') {
p += 2;
while (*p == ' ' || *p == '\t')
p++;
if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E'
&& p[4] == 'N' && p[5] == 'T') {
p += 6;
while (*p == ' ' || *p == '\t')
p++;
if (*p == '*')
com = 1;
else {
if (*p == 'O') {
if (*++p == 'N')
p++, com = 1;
else
if (*p == 'F' && *++p == 'F')
p++, com = 2;
}
}
while (*p == ' ' || *p == '\t')
p++;
if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com) {
if (s_com != e_com || s_lab != e_lab || s_code != e_code)
dump_line();
if (!(inhibit_formatting = com - 1)) {
n_real_blanklines = 0;
postfix_blankline_requested = 0;
prefix_blankline_requested = 0;
suppress_blanklines = 1;
}
}
}
}
}
}
if (inhibit_formatting) {
p = in_buffer;
do
putc(*p, output);
while (*p++ != '\n');
}
}
/*
* Copyright (C) 1976 by the Board of Trustees of the University of Illinois
*
* All rights reserved
*
*
* NAME: pad_output
*
* FUNCTION: Writes tabs and spaces to move the current column up to the desired
* position.
*
* ALGORITHM: Put tabs and/or blanks into pobuf, then write pobuf.
*
* PARAMETERS: current integer The current column target
* target integer The desired column
*
* RETURNS: Integer value of the new column. (If current >= target, no action is
* taken, and current is returned.
*
* GLOBALS: None
*
* CALLS: write (sys)
*
* CALLED BY: dump_line
*
* HISTORY: initial coding November 1976 D A Willcox of CAC
*
*/
int
pad_output(int current, int target)
{
int curr; /* internal column pointer */
int tcur;
if (troff)
fprintf(output, "\\h'|%dp'", (target - 1) * 7);
else {
if (current >= target)
return (current); /* line is already long enough */
curr = current;
while ((tcur = ((curr - 1) & tabmask) + tabsize + 1) <= target) {
putc('\t', output);
curr = tcur;
}
while (curr++ < target)
putc(' ', output); /* pad with final blanks */
}
return (target);
}
/*
* Copyright (C) 1976 by the Board of Trustees of the University of Illinois
*
* All rights reserved
*
*
* NAME: count_spaces
*
* FUNCTION: Find out where printing of a given string will leave the current
* character position on output.
*
* ALGORITHM: Run thru input string and add appropriate values to current
* position.
*
* RETURNS: Integer value of position after printing "buffer" starting in column
* "current".
*
* HISTORY: initial coding November 1976 D A Willcox of CAC
*
*/
int
count_spaces(int current, char *buffer)
/*
* this routine figures out where the character position will be after
* printing the text in buffer starting at column "current"
*/
{
char *buf; /* used to look thru buffer */
int cur; /* current character counter */
cur = current;
for (buf = buffer; *buf != '\0'; ++buf) {
switch (*buf) {
case '\n':
case 014: /* form feed */
cur = 1;
break;
case '\t':
cur = ((cur - 1) & tabmask) + tabsize + 1;
break;
case 010: /* backspace */
--cur;
break;
default:
++cur;
break;
} /* end of switch */
} /* end of for loop */
return (cur);
}
int found_err;
void
diag(int level, const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
if (level)
found_err = 1;
if (output == stdout) {
fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no);
vfprintf(stdout, msg, ap);
fprintf(stdout, " */\n");
} else {
fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no);
vfprintf(stdout, msg, ap);
fprintf(stderr, "\n");
}
va_end(ap);
}
void
writefdef(struct fstate *f, int nm)
{
fprintf(output, ".ds f%c %s\n.nr s%c %d\n",
nm, f->font, nm, f->size);
}
char *
chfont(struct fstate *of, struct fstate *nf, char *s)
{
if (of->font[0] != nf->font[0]
|| of->font[1] != nf->font[1]) {
*s++ = '\\';
*s++ = 'f';
if (nf->font[1]) {
*s++ = '(';
*s++ = nf->font[0];
*s++ = nf->font[1];
} else
*s++ = nf->font[0];
}
if (nf->size != of->size) {
*s++ = '\\';
*s++ = 's';
if (nf->size < of->size) {
*s++ = '-';
*s++ = '0' + of->size - nf->size;
} else {
*s++ = '+';
*s++ = '0' + nf->size - of->size;
}
}
return s;
}
void
parsefont(struct fstate *f, const char *s0)
{
const char *s = s0;
int sizedelta = 0;
memset(f, 0, sizeof *f);
while (*s) {
if (isdigit((unsigned char)*s))
f->size = f->size * 10 + *s - '0';
else
if (isupper((unsigned char)*s)) {
if (f->font[0])
f->font[1] = *s;
else
f->font[0] = *s;
} else
if (*s == 'c')
f->allcaps = 1;
else
if (*s == '+')
sizedelta++;
else
if (*s == '-')
sizedelta--;
else {
fprintf(stderr, "indent: bad font specification: %s\n", s0);
exit(1);
}
s++;
}
if (f->font[0] == 0)
f->font[0] = 'R';
if (bodyf.size == 0)
bodyf.size = 11;
if (f->size == 0)
f->size = bodyf.size + sizedelta;
else
if (sizedelta > 0)
f->size += bodyf.size;
else
f->size = bodyf.size - f->size;
}

630
usr.bin/indent/lexi.c Normal file
View file

@ -0,0 +1,630 @@
/* $NetBSD: lexi.c,v 1.13 2009/04/12 11:09:49 lukem Exp $ */
/*
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* Copyright (c) 1985 Sun Microsystems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lexi.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lexi.c,v 1.13 2009/04/12 11:09:49 lukem Exp $");
#endif
#endif /* not lint */
/*
* Here we have the token scanner for indent. It scans off one token and puts
* it in the global variable "token". It returns a code, indicating the type
* of token scanned.
*/
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "indent_globs.h"
#include "indent_codes.h"
#define alphanum 1
#define opchar 3
struct templ {
const char *rwd;
int rwcode;
};
struct templ specials[1000] =
{
{"switch", 1},
{"case", 2},
{"break", 0},
{"struct", 3},
{"union", 3},
{"enum", 3},
{"default", 2},
{"int", 4},
{"char", 4},
{"float", 4},
{"double", 4},
{"long", 4},
{"short", 4},
{"typdef", 4},
{"unsigned", 4},
{"register", 4},
{"static", 4},
{"global", 4},
{"extern", 4},
{"void", 4},
{"goto", 0},
{"return", 0},
{"if", 5},
{"while", 5},
{"for", 5},
{"else", 6},
{"do", 6},
{"sizeof", 7},
{0, 0}
};
char chartype[128] =
{ /* this is used to facilitate the decision of
* what type (alphanumeric, operator) each
* character is */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 3, 0, 0, 1, 3, 3, 0,
0, 0, 3, 3, 0, 3, 0, 3,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 0, 0, 3, 3, 3, 3,
0, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 0, 0, 3, 1,
0, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 3, 0, 3, 0
};
int
lexi(void)
{
int unary_delim; /* this is set to 1 if the current token
*
* forces a following operator to be unary */
static int last_code; /* the last token type returned */
static int l_struct; /* set to 1 if the last token was 'struct' */
int code; /* internal code to be returned */
char qchar; /* the delimiter character for a string */
e_token = s_token; /* point to start of place to save token */
unary_delim = false;
ps.col_1 = ps.last_nl; /* tell world that this token started in
* column 1 iff the last thing scanned was nl */
ps.last_nl = false;
while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */
ps.col_1 = false; /* leading blanks imply token is not
* in column 1 */
if (++buf_ptr >= buf_end)
fill_buffer();
}
/* Scan an alphanumeric token */
if (chartype[(int) *buf_ptr] == alphanum ||
(buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) {
/*
* we have a character or number
*/
const char *j; /* used for searching thru list of
* reserved words */
struct templ *p;
if (isdigit((unsigned char)*buf_ptr) ||
(buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) {
int seendot = 0, seenexp = 0, seensfx = 0;
if (*buf_ptr == '0' &&
(buf_ptr[1] == 'x' || buf_ptr[1] == 'X')) {
*e_token++ = *buf_ptr++;
*e_token++ = *buf_ptr++;
while (isxdigit((unsigned char)*buf_ptr)) {
CHECK_SIZE_TOKEN;
*e_token++ = *buf_ptr++;
}
} else {
while (1) {
if (*buf_ptr == '.') {
if (seendot)
break;
else
seendot++;
}
CHECK_SIZE_TOKEN;
*e_token++ = *buf_ptr++;
if (!isdigit((unsigned char)*buf_ptr)
&& *buf_ptr != '.') {
if ((*buf_ptr != 'E'
&& *buf_ptr != 'e') || seenexp)
break;
else {
seenexp++;
seendot++;
CHECK_SIZE_TOKEN;
*e_token++ = *buf_ptr++;
if (*buf_ptr == '+' || *buf_ptr == '-')
*e_token++ = *buf_ptr++;
}
}
}
}
if (*buf_ptr == 'F' || *buf_ptr == 'f') {
/* float constant */
*e_token++ = *buf_ptr++;
} else {
/* integer constant */
while (1) {
if (!(seensfx & 1) &&
(*buf_ptr == 'U' ||
*buf_ptr == 'u')) {
CHECK_SIZE_TOKEN;
*e_token++ = *buf_ptr++;
seensfx |= 1;
continue;
}
if (!(seensfx & 2) &&
(*buf_ptr == 'L' ||
*buf_ptr == 'l')) {
CHECK_SIZE_TOKEN;
if (buf_ptr[1] == buf_ptr[0])
*e_token++ = *buf_ptr++;
*e_token++ = *buf_ptr++;
seensfx |= 2;
continue;
}
break;
}
}
} else
while (chartype[(int) *buf_ptr] == alphanum) { /* copy it over */
CHECK_SIZE_TOKEN;
*e_token++ = *buf_ptr++;
if (buf_ptr >= buf_end)
fill_buffer();
}
*e_token++ = '\0';
while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */
if (++buf_ptr >= buf_end)
fill_buffer();
}
ps.its_a_keyword = false;
ps.sizeof_keyword = false;
if (l_struct) { /* if last token was 'struct', then this token
* should be treated as a declaration */
l_struct = false;
last_code = ident;
ps.last_u_d = true;
return (decl);
}
ps.last_u_d = false; /* Operator after indentifier is
* binary */
last_code = ident; /* Remember that this is the code we
* will return */
/*
* This loop will check if the token is a keyword.
*/
for (p = specials; (j = p->rwd) != 0; p++) {
char *pt = s_token; /* point at scanned token */
if (*j++ != *pt++ || *j++ != *pt++)
continue; /* This test depends on the
* fact that identifiers are
* always at least 1 character
* long (ie. the first two
* bytes of the identifier are
* always meaningful) */
if (pt[-1] == 0)
break; /* If its a one-character identifier */
while (*pt++ == *j)
if (*j++ == 0)
goto found_keyword; /* I wish that C had a
* multi-level break... */
}
if (p->rwd) { /* we have a keyword */
found_keyword:
ps.its_a_keyword = true;
ps.last_u_d = true;
switch (p->rwcode) {
case 1:/* it is a switch */
return (swstmt);
case 2:/* a case or default */
return (casestmt);
case 3:/* a "struct" */
if (ps.p_l_follow)
break; /* inside parens: cast */
l_struct = true;
/*
* Next time around, we will want to know that we have had a
* 'struct'
*/
case 4:/* one of the declaration keywords */
if (ps.p_l_follow) {
ps.cast_mask |= 1 << ps.p_l_follow;
break; /* inside parens: cast */
}
last_code = decl;
return (decl);
case 5:/* if, while, for */
return (sp_paren);
case 6:/* do, else */
return (sp_nparen);
case 7:
ps.sizeof_keyword = true;
default: /* all others are treated like any
* other identifier */
return (ident);
} /* end of switch */
} /* end of if (found_it) */
if (*buf_ptr == '(' && ps.tos <= 1 && ps.ind_level == 0) {
char *tp = buf_ptr;
while (tp < buf_end)
if (*tp++ == ')' && (*tp == ';' || *tp == ','))
goto not_proc;
strncpy(ps.procname, token, sizeof ps.procname - 1);
ps.in_parameter_declaration = 1;
rparen_count = 1;
not_proc: ;
}
/*
* The following hack attempts to guess whether or not the current
* token is in fact a declaration keyword -- one that has been
* typedefd
*/
if (((*buf_ptr == '*' && buf_ptr[1] != '=') ||
isalpha((unsigned char)*buf_ptr) || *buf_ptr == '_')
&& !ps.p_l_follow
&& !ps.block_init
&& (ps.last_token == rparen || ps.last_token == semicolon ||
ps.last_token == decl ||
ps.last_token == lbrace || ps.last_token == rbrace)) {
ps.its_a_keyword = true;
ps.last_u_d = true;
last_code = decl;
return decl;
}
if (last_code == decl) /* if this is a declared variable,
* then following sign is unary */
ps.last_u_d = true; /* will make "int a -1" work */
last_code = ident;
return (ident); /* the ident is not in the list */
} /* end of procesing for alpanum character */
/* Scan a non-alphanumeric token */
*e_token++ = *buf_ptr; /* if it is only a one-character token, it is
* moved here */
*e_token = '\0';
if (++buf_ptr >= buf_end)
fill_buffer();
switch (*token) {
case '\n':
unary_delim = ps.last_u_d;
ps.last_nl = true; /* remember that we just had a newline */
code = (had_eof ? 0 : newline);
/*
* if data has been exausted, the newline is a dummy, and we should
* return code to stop
*/
break;
case '\'': /* start of quoted character */
case '"': /* start of string */
qchar = *token;
if (troff) {
e_token[-1] = '`';
if (qchar == '"')
*e_token++ = '`';
e_token = chfont(&bodyf, &stringf, e_token);
}
do { /* copy the string */
while (1) { /* move one character or
* [/<char>]<char> */
if (*buf_ptr == '\n') {
printf("%d: Unterminated literal\n", line_no);
goto stop_lit;
}
CHECK_SIZE_TOKEN; /* Only have to do this
* once in this loop,
* since CHECK_SIZE
* guarantees that there
* are at least 5
* entries left */
*e_token = *buf_ptr++;
if (buf_ptr >= buf_end)
fill_buffer();
if (*e_token == BACKSLASH) { /* if escape, copy extra
* char */
if (*buf_ptr == '\n') /* check for escaped
* newline */
++line_no;
if (troff) {
*++e_token = BACKSLASH;
if (*buf_ptr == BACKSLASH)
*++e_token = BACKSLASH;
}
*++e_token = *buf_ptr++;
++e_token; /* we must increment
* this again because we
* copied two chars */
if (buf_ptr >= buf_end)
fill_buffer();
} else
break; /* we copied one character */
} /* end of while (1) */
} while (*e_token++ != qchar);
if (troff) {
e_token = chfont(&stringf, &bodyf, e_token - 1);
if (qchar == '"')
*e_token++ = '\'';
}
stop_lit:
code = ident;
break;
case ('('):
case ('['):
unary_delim = true;
code = lparen;
break;
case (')'):
case (']'):
code = rparen;
break;
case '#':
unary_delim = ps.last_u_d;
code = preesc;
break;
case '?':
unary_delim = true;
code = question;
break;
case (':'):
code = colon;
unary_delim = true;
break;
case (';'):
unary_delim = true;
code = semicolon;
break;
case ('{'):
unary_delim = true;
/*
* if (ps.in_or_st) ps.block_init = 1;
*/
/* ? code = ps.block_init ? lparen : lbrace; */
code = lbrace;
break;
case ('}'):
unary_delim = true;
/* ? code = ps.block_init ? rparen : rbrace; */
code = rbrace;
break;
case 014: /* a form feed */
unary_delim = ps.last_u_d;
ps.last_nl = true; /* remember this so we can set
* 'ps.col_1' right */
code = form_feed;
break;
case (','):
unary_delim = true;
code = comma;
break;
case '.':
unary_delim = false;
code = period;
break;
case '-':
case '+': /* check for -, +, --, ++ */
code = (ps.last_u_d ? unary_op : binary_op);
unary_delim = true;
if (*buf_ptr == token[0]) {
/* check for doubled character */
*e_token++ = *buf_ptr++;
/* buffer overflow will be checked at end of loop */
if (last_code == ident || last_code == rparen) {
code = (ps.last_u_d ? unary_op : postop);
/* check for following ++ or -- */
unary_delim = false;
}
} else
if (*buf_ptr == '=')
/* check for operator += */
*e_token++ = *buf_ptr++;
else
if (*buf_ptr == '>') {
/* check for operator -> */
*e_token++ = *buf_ptr++;
if (!pointer_as_binop) {
unary_delim = false;
code = unary_op;
ps.want_blank = false;
}
}
break; /* buffer overflow will be checked at end of
* switch */
case '=':
if (ps.in_or_st)
ps.block_init = 1;
#ifdef undef
if (chartype[*buf_ptr] == opchar) { /* we have two char
* assignment */
e_token[-1] = *buf_ptr++;
if ((e_token[-1] == '<' || e_token[-1] == '>') && e_token[-1] == *buf_ptr)
*e_token++ = *buf_ptr++;
*e_token++ = '='; /* Flip =+ to += */
*e_token = 0;
}
#else
if (*buf_ptr == '=') { /* == */
*e_token++ = '='; /* Flip =+ to += */
buf_ptr++;
*e_token = 0;
}
#endif
code = binary_op;
unary_delim = true;
break;
/* can drop thru!!! */
case '>':
case '<':
case '!': /* ops like <, <<, <=, !=, etc */
if (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=') {
*e_token++ = *buf_ptr;
if (++buf_ptr >= buf_end)
fill_buffer();
}
if (*buf_ptr == '=')
*e_token++ = *buf_ptr++;
code = (ps.last_u_d ? unary_op : binary_op);
unary_delim = true;
break;
default:
if (token[0] == '/' && *buf_ptr == '*') {
/* it is start of comment */
*e_token++ = '*';
if (++buf_ptr >= buf_end)
fill_buffer();
code = comment;
unary_delim = ps.last_u_d;
break;
}
while (*(e_token - 1) == *buf_ptr || *buf_ptr == '=') {
/*
* handle ||, &&, etc, and also things as in int *****i
*/
*e_token++ = *buf_ptr;
if (++buf_ptr >= buf_end)
fill_buffer();
}
code = (ps.last_u_d ? unary_op : binary_op);
unary_delim = true;
} /* end of switch */
if (code != newline) {
l_struct = false;
last_code = code;
}
if (buf_ptr >= buf_end) /* check for input buffer empty */
fill_buffer();
ps.last_u_d = unary_delim;
*e_token = '\0'; /* null terminate the token */
return (code);
}
/*
* Add the given keyword to the keyword table, using val as the keyword type
*/
void
addkey(char *key, int val)
{
struct templ *p = specials;
while (p->rwd)
if (p->rwd[0] == key[0] && strcmp(p->rwd, key) == 0)
return;
else
p++;
if (p >= specials + sizeof specials / sizeof specials[0])
return; /* For now, table overflows are silently
* ignored */
p->rwd = key;
p->rwcode = val;
p[1].rwd = 0;
p[1].rwcode = 0;
}

View file

360
usr.bin/indent/parse.c Normal file
View file

@ -0,0 +1,360 @@
/* $NetBSD: parse.c,v 1.7 2003/08/07 11:14:09 agc Exp $ */
/*
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* Copyright (c) 1985 Sun Microsystems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: parse.c,v 1.7 2003/08/07 11:14:09 agc Exp $");
#endif
#endif /* not lint */
#include <stdio.h>
#include "indent_globs.h"
#include "indent_codes.h"
/* tk: the code for the construct scanned */
void
parse(int tk)
{
int i;
#ifdef debug
printf("%2d - %s\n", tk, token);
#endif
while (ps.p_stack[ps.tos] == ifhead && tk != elselit) {
/* true if we have an if without an else */
ps.p_stack[ps.tos] = stmt; /* apply the if(..) stmt ::=
* stmt reduction */
reduce(); /* see if this allows any reduction */
}
switch (tk) { /* go on and figure out what to do with the
* input */
case decl: /* scanned a declaration word */
ps.search_brace = btype_2;
/* indicate that following brace should be on same line */
if (ps.p_stack[ps.tos] != decl) { /* only put one
* declaration onto
* stack */
break_comma = true; /* while in declaration,
* newline should be forced
* after comma */
ps.p_stack[++ps.tos] = decl;
ps.il[ps.tos] = ps.i_l_follow;
if (ps.ljust_decl) { /* only do if we want left
* justified declarations */
ps.ind_level = 0;
for (i = ps.tos - 1; i > 0; --i)
if (ps.p_stack[i] == decl)
++ps.ind_level; /* indentation is number
* of declaration levels
* deep we are */
ps.i_l_follow = ps.ind_level;
}
}
break;
case ifstmt: /* scanned if (...) */
if (ps.p_stack[ps.tos] == elsehead && ps.else_if) /* "else if ..." */
ps.i_l_follow = ps.il[ps.tos];
case dolit: /* 'do' */
case forstmt: /* for (...) */
ps.p_stack[++ps.tos] = tk;
ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
++ps.i_l_follow;/* subsequent statements should be indented 1 */
ps.search_brace = btype_2;
break;
case lbrace: /* scanned { */
break_comma = false; /* don't break comma in an initial
* list */
if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl
|| ps.p_stack[ps.tos] == stmtl)
++ps.i_l_follow; /* it is a random, isolated
* stmt group or a declaration */
else {
if (s_code == e_code) {
/*
* only do this if there is nothing on the line
*/
--ps.ind_level;
/*
* it is a group as part of a while, for, etc.
*/
if (ps.p_stack[ps.tos] == swstmt && ps.case_indent >= 1)
--ps.ind_level;
/*
* for a switch, brace should be two levels out from the code
*/
}
}
ps.p_stack[++ps.tos] = lbrace;
ps.il[ps.tos] = ps.ind_level;
ps.p_stack[++ps.tos] = stmt;
/* allow null stmt between braces */
ps.il[ps.tos] = ps.i_l_follow;
break;
case whilestmt: /* scanned while (...) */
if (ps.p_stack[ps.tos] == dohead) {
/* it is matched with do stmt */
ps.ind_level = ps.i_l_follow = ps.il[ps.tos];
ps.p_stack[++ps.tos] = whilestmt;
ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
} else { /* it is a while loop */
ps.p_stack[++ps.tos] = whilestmt;
ps.il[ps.tos] = ps.i_l_follow;
++ps.i_l_follow;
ps.search_brace = btype_2;
}
break;
case elselit: /* scanned an else */
if (ps.p_stack[ps.tos] != ifhead)
diag(1, "Unmatched 'else'");
else {
ps.ind_level = ps.il[ps.tos]; /* indentation for else
* should be same as for
* if */
ps.i_l_follow = ps.ind_level + 1; /* everything following
* should be in 1 level */
ps.p_stack[ps.tos] = elsehead;
/* remember if with else */
ps.search_brace = btype_2 | ps.else_if;
}
break;
case rbrace: /* scanned a } */
/* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */
if (ps.p_stack[ps.tos - 1] == lbrace) {
ps.ind_level = ps.i_l_follow = ps.il[--ps.tos];
ps.p_stack[ps.tos] = stmt;
} else
diag(1, "Stmt nesting error.");
break;
case swstmt: /* had switch (...) */
ps.p_stack[++ps.tos] = swstmt;
ps.cstk[ps.tos] = case_ind;
/* save current case indent level */
ps.il[ps.tos] = ps.i_l_follow;
case_ind = ps.i_l_follow + ps.case_indent; /* cases should be one
* level down from
* switch */
ps.i_l_follow += ps.case_indent + 1; /* statements should be
* two levels in */
ps.search_brace = btype_2;
break;
case semicolon: /* this indicates a simple stmt */
break_comma = false; /* turn off flag to break after commas
* in a declaration */
ps.p_stack[++ps.tos] = stmt;
ps.il[ps.tos] = ps.ind_level;
break;
default: /* this is an error */
diag(1, "Unknown code to parser");
return;
} /* end of switch */
reduce(); /* see if any reduction can be done */
#ifdef debug
for (i = 1; i <= ps.tos; ++i)
printf("(%d %d)", ps.p_stack[i], ps.il[i]);
printf("\n");
#endif
}
/*
* NAME: reduce
*
* FUNCTION: Implements the reduce part of the parsing algorithm
*
* ALGORITHM: The following reductions are done. Reductions are repeated
* until no more are possible.
*
* Old TOS New TOS
* <stmt> <stmt> <stmtl>
* <stmtl> <stmt> <stmtl>
* do <stmt> "dostmt"
* if <stmt> "ifstmt"
* switch <stmt> <stmt>
* decl <stmt> <stmt>
* "ifelse" <stmt> <stmt>
* for <stmt> <stmt>
* while <stmt> <stmt>
* "dostmt" while <stmt>
*
* On each reduction, ps.i_l_follow (the indentation for the following line)
* is set to the indentation level associated with the old TOS.
*
* PARAMETERS: None
*
* RETURNS: Nothing
*
* GLOBALS: ps.cstk ps.i_l_follow = ps.il ps.p_stack = ps.tos =
*
* CALLS: None
*
* CALLED BY: parse
*
* HISTORY: initial coding November 1976 D A Willcox of CAC
*
*/
/*----------------------------------------------*\
| REDUCTION PHASE |
\*----------------------------------------------*/
void
reduce(void)
{
int i;
for (;;) { /* keep looping until there is nothing left to
* reduce */
switch (ps.p_stack[ps.tos]) {
case stmt:
switch (ps.p_stack[ps.tos - 1]) {
case stmt:
case stmtl:
/* stmtl stmt or stmt stmt */
ps.p_stack[--ps.tos] = stmtl;
break;
case dolit: /* <do> <stmt> */
ps.p_stack[--ps.tos] = dohead;
ps.i_l_follow = ps.il[ps.tos];
break;
case ifstmt:
/* <if> <stmt> */
ps.p_stack[--ps.tos] = ifhead;
for (i = ps.tos - 1;
(
ps.p_stack[i] != stmt
&&
ps.p_stack[i] != stmtl
&&
ps.p_stack[i] != lbrace
);
--i);
ps.i_l_follow = ps.il[i];
/*
* for the time being, we will assume that there is no else on
* this if, and set the indentation level accordingly. If an
* else is scanned, it will be fixed up later
*/
break;
case swstmt:
/* <switch> <stmt> */
case_ind = ps.cstk[ps.tos - 1];
case decl: /* finish of a declaration */
case elsehead:
/* <<if> <stmt> else> <stmt> */
case forstmt:
/* <for> <stmt> */
case whilestmt:
/* <while> <stmt> */
ps.p_stack[--ps.tos] = stmt;
ps.i_l_follow = ps.il[ps.tos];
break;
default: /* <anything else> <stmt> */
return;
} /* end of section for <stmt> on top of stack */
break;
case whilestmt:/* while (...) on top */
if (ps.p_stack[ps.tos - 1] == dohead) {
/* it is termination of a do while */
ps.p_stack[--ps.tos] = stmt;
break;
} else
return;
default: /* anything else on top */
return;
}
}
}

461
usr.bin/indent/pr_comment.c Normal file
View file

@ -0,0 +1,461 @@
/* $NetBSD: pr_comment.c,v 1.9 2003/08/07 11:14:09 agc Exp $ */
/*
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* Copyright (c) 1985 Sun Microsystems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)pr_comment.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: pr_comment.c,v 1.9 2003/08/07 11:14:09 agc Exp $");
#endif
#endif /* not lint */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "indent_globs.h"
/*
* NAME:
* pr_comment
*
* FUNCTION:
* This routine takes care of scanning and printing comments.
*
* ALGORITHM:
* 1) Decide where the comment should be aligned, and if lines should
* be broken.
* 2) If lines should not be broken and filled, just copy up to end of
* comment.
* 3) If lines should be filled, then scan thru input_buffer copying
* characters to com_buf. Remember where the last blank, tab, or
* newline was. When line is filled, print up to last blank and
* continue copying.
*
* HISTORY:
* November 1976 D A Willcox of CAC Initial coding
* 12/6/76 D A Willcox of CAC Modification to handle
* UNIX-style comments
*
*/
/*
* this routine processes comments. It makes an attempt to keep comments from
* going over the max line length. If a line is too long, it moves everything
* from the last blank to the next comment line. Blanks and tabs from the
* beginning of the input line are removed
*/
void
pr_comment(void)
{
int now_col; /* column we are in now */
int adj_max_col; /* Adjusted max_col for when we decide to
* spill comments over the right margin */
char *last_bl; /* points to the last blank in the output
* buffer */
char *t_ptr; /* used for moving string */
int unix_comment; /* tri-state variable used to decide if it is
* a unix-style comment. 0 means only blanks
* since start, 1 means regular style comment,
* 2 means unix style comment */
int break_delim = comment_delimiter_on_blankline;
int l_just_saw_decl = ps.just_saw_decl;
/*
* int ps.last_nl = 0; / * true iff the last significant thing
* weve seen is a newline
*/
int one_liner = 1; /* true iff this comment is a one-liner */
adj_max_col = max_col;
ps.just_saw_decl = 0;
last_bl = 0; /* no blanks found so far */
ps.box_com = false; /* at first, assume that we are not in a boxed
* comment or some other comment that should
* not be touched */
++ps.out_coms; /* keep track of number of comments */
unix_comment = 1; /* set flag to let us figure out if there is a
* unix-style comment ** DISABLED: use 0 to
* reenable this hack! */
/* Figure where to align and how to treat the comment */
if (ps.col_1 && !format_col1_comments) { /* if comment starts in
* column 1 it should
* not be touched */
ps.box_com = true;
ps.com_col = 1;
} else {
if (*buf_ptr == '-' || *buf_ptr == '*' || *buf_ptr == '\n') {
ps.box_com = true; /* a comment with a '-', '*'
* or newline immediately
* after the start comment is
* assumed to be a boxed
* comment */
break_delim = 0;
}
if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) {
/* klg: check only if this line is blank */
/*
* If this (*and previous lines are*) blank, dont put comment way
* out at left
*/
ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
adj_max_col = block_comment_max_col;
if (ps.com_col <= 1)
ps.com_col = 1 + !format_col1_comments;
} else {
int target_col;
break_delim = 0;
if (s_code != e_code)
target_col = count_spaces(compute_code_target(), s_code);
else {
target_col = 1;
if (s_lab != e_lab)
target_col = count_spaces(compute_label_target(), s_lab);
}
ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? ps.decl_com_ind : ps.com_ind;
if (ps.com_col < target_col)
ps.com_col = ((target_col + 7) & ~7) + 1;
if (ps.com_col + 24 > adj_max_col)
adj_max_col = ps.com_col + 24;
}
}
if (ps.box_com) {
buf_ptr[-2] = 0;
ps.n_comment_delta = 1 - count_spaces(1, in_buffer);
buf_ptr[-2] = '/';
} else {
ps.n_comment_delta = 0;
while (*buf_ptr == ' ' || *buf_ptr == '\t')
buf_ptr++;
}
ps.comment_delta = 0;
*e_com++ = '/'; /* put '/' + '*' into buffer */
*e_com++ = '*';
if (*buf_ptr != ' ' && !ps.box_com)
*e_com++ = ' ';
*e_com = '\0';
if (troff) {
now_col = 1;
adj_max_col = 80;
} else
now_col = count_spaces(ps.com_col, s_com); /* figure what column we
* would be in if we
* printed the comment
* now */
/* Start to copy the comment */
while (1) { /* this loop will go until the comment is
* copied */
if (!iscntrl((unsigned char)*buf_ptr) && *buf_ptr != '*')
ps.last_nl = 0;
CHECK_SIZE_COM;
switch (*buf_ptr) { /* this checks for various spcl cases */
case 014: /* check for a form feed */
if (!ps.box_com) { /* in a text comment, break
* the line here */
ps.use_ff = true;
/* fix so dump_line uses a form feed */
dump_line();
last_bl = 0;
*e_com++ = ' ';
*e_com++ = '*';
*e_com++ = ' ';
while (*++buf_ptr == ' ' || *buf_ptr == '\t');
} else {
if (++buf_ptr >= buf_end)
fill_buffer();
*e_com++ = 014;
}
break;
case '\n':
if (had_eof) { /* check for unexpected eof */
printf("Unterminated comment\n");
*e_com = '\0';
dump_line();
return;
}
one_liner = 0;
if (ps.box_com || ps.last_nl) { /* if this is a boxed
* comment, we dont
* ignore the newline */
if (s_com == e_com) {
*e_com++ = ' ';
*e_com++ = ' ';
}
*e_com = '\0';
if (!ps.box_com && e_com - s_com > 3) {
if (break_delim == 1 && s_com[0] == '/'
&& s_com[1] == '*' && s_com[2] == ' ') {
char *t = e_com;
break_delim = 2;
e_com = s_com + 2;
*e_com = 0;
if (blanklines_before_blockcomments)
prefix_blankline_requested = 1;
dump_line();
e_com = t;
s_com[0] = s_com[1] = s_com[2] = ' ';
}
dump_line();
CHECK_SIZE_COM;
*e_com++ = ' ';
*e_com++ = ' ';
}
dump_line();
now_col = ps.com_col;
} else {
ps.last_nl = 1;
if (unix_comment != 1) { /* we not are in
* unix_style comment */
if (unix_comment == 0 && s_code == e_code) {
/*
* if it is a UNIX-style comment, ignore the
* requirement that previous line be blank for
* unindention
*/
ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
if (ps.com_col <= 1)
ps.com_col = 2;
}
unix_comment = 2; /* permanently remember
* that we are in this
* type of comment */
dump_line();
++line_no;
now_col = ps.com_col;
*e_com++ = ' ';
/*
* fix so that the star at the start of the line will line
* up
*/
do /* flush leading white space */
if (++buf_ptr >= buf_end)
fill_buffer();
while (*buf_ptr == ' ' || *buf_ptr == '\t');
break;
}
if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t')
last_bl = e_com - 1;
/*
* if there was a space at the end of the last line, remember
* where it was
*/
else { /* otherwise, insert one */
last_bl = e_com;
CHECK_SIZE_COM;
*e_com++ = ' ';
++now_col;
}
}
++line_no; /* keep track of input line number */
if (!ps.box_com) {
int nstar = 1;
do { /* flush any blanks and/or tabs at
* start of next line */
if (++buf_ptr >= buf_end)
fill_buffer();
if (*buf_ptr == '*' && --nstar >= 0) {
if (++buf_ptr >= buf_end)
fill_buffer();
if (*buf_ptr == '/')
goto end_of_comment;
}
} while (*buf_ptr == ' ' || *buf_ptr == '\t');
} else
if (++buf_ptr >= buf_end)
fill_buffer();
break; /* end of case for newline */
case '*': /* must check for possibility of being at end
* of comment */
if (++buf_ptr >= buf_end) /* get to next char
* after * */
fill_buffer();
if (unix_comment == 0) /* set flag to show we are not
* in unix-style comment */
unix_comment = 1;
if (*buf_ptr == '/') { /* it is the end!!! */
end_of_comment:
if (++buf_ptr >= buf_end)
fill_buffer();
if (*(e_com - 1) != ' ' && !ps.box_com) { /* insure blank before
* end */
*e_com++ = ' ';
++now_col;
}
if (break_delim == 1 && !one_liner && s_com[0] == '/'
&& s_com[1] == '*' && s_com[2] == ' ') {
char *t = e_com;
break_delim = 2;
e_com = s_com + 2;
*e_com = 0;
if (blanklines_before_blockcomments)
prefix_blankline_requested = 1;
dump_line();
e_com = t;
s_com[0] = s_com[1] = s_com[2] = ' ';
}
if (break_delim == 2 && e_com > s_com + 3
/* now_col > adj_max_col - 2 && !ps.box_com */ ) {
*e_com = '\0';
dump_line();
now_col = ps.com_col;
}
CHECK_SIZE_COM;
*e_com++ = '*';
*e_com++ = '/';
*e_com = '\0';
ps.just_saw_decl = l_just_saw_decl;
return;
} else {/* handle isolated '*' */
*e_com++ = '*';
++now_col;
}
break;
default: /* we have a random char */
if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t')
unix_comment = 1; /* we are not in
* unix-style comment */
*e_com = *buf_ptr++;
if (buf_ptr >= buf_end)
fill_buffer();
if (*e_com == '\t') /* keep track of column */
now_col = ((now_col - 1) & tabmask) + tabsize + 1;
else
if (*e_com == '\b') /* this is a backspace */
--now_col;
else
++now_col;
if (*e_com == ' ' || *e_com == '\t')
last_bl = e_com;
/* remember we saw a blank */
++e_com;
if (now_col > adj_max_col && !ps.box_com && unix_comment == 1
&& !iscntrl((unsigned char)e_com[-1])
&& !isblank((unsigned char)e_com[-1])) {
/*
* the comment is too long, it must be broken up
*/
if (break_delim == 1 && s_com[0] == '/'
&& s_com[1] == '*' && s_com[2] == ' ') {
char *t = e_com;
break_delim = 2;
e_com = s_com + 2;
*e_com = 0;
if (blanklines_before_blockcomments)
prefix_blankline_requested = 1;
dump_line();
e_com = t;
s_com[0] = s_com[1] = s_com[2] = ' ';
}
if (last_bl == 0) { /* we have seen no
* blanks */
last_bl = e_com; /* fake it */
*e_com++ = ' ';
}
*e_com = '\0'; /* print what we have */
*last_bl = '\0';
while (last_bl > s_com && iscntrl((unsigned char)last_bl[-1]) )
*--last_bl = 0;
e_com = last_bl;
dump_line();
*e_com++ = ' '; /* add blanks for continuation */
*e_com++ = ' ';
*e_com++ = ' ';
t_ptr = last_bl + 1;
last_bl = 0;
if (t_ptr >= e_com) {
while (*t_ptr == ' ' || *t_ptr == '\t')
t_ptr++;
while (*t_ptr != '\0') { /* move unprinted part
* of comment down in
* buffer */
if (*t_ptr == ' ' || *t_ptr == '\t')
last_bl = e_com;
*e_com++ = *t_ptr++;
}
}
*e_com = '\0';
now_col = count_spaces(ps.com_col, s_com); /* recompute current
* position */
}
break;
}
}
}