Imported indent

This commit is contained in:
Ben Gras 2005-07-22 18:30:14 +00:00
parent ca80161f40
commit 3a68bd323a
11 changed files with 4054 additions and 0 deletions

21
commands/indent/Makefile Normal file
View file

@ -0,0 +1,21 @@
# Makefile for indent
CFLAGS= -c -O -D_MINIX -D_POSIX_SOURCE -wo -m
all: indent
OBJ = args.o comment.o lexi.o indent.o parse.o io.o
indent: ${OBJ}
$(CC) -o indent -i ${OBJ}
install -S 32kw $@
install: /usr/bin/indent
/usr/bin/indent: indent
install -cs -o bin indent $@
$(OBJ): globs.h codes.h
clean:
rm -f *.bak *.o core indent

287
commands/indent/args.c Normal file
View file

@ -0,0 +1,287 @@
/**
* 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);
}
}

54
commands/indent/codes.h Normal file
View file

@ -0,0 +1,54 @@
/**
* 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

457
commands/indent/comment.c Normal file
View file

@ -0,0 +1,457 @@
/**
* 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;
}
}
}

308
commands/indent/globs.h Normal file
View file

@ -0,0 +1,308 @@
/**
* 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];

1374
commands/indent/indent.c Normal file

File diff suppressed because it is too large Load diff

View file

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

636
commands/indent/io.c Normal file
View file

@ -0,0 +1,636 @@
/**
* 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;
}

571
commands/indent/lexi.c Normal file
View file

@ -0,0 +1,571 @@
/**
* 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;
}

319
commands/indent/parse.c Normal file
View file

@ -0,0 +1,319 @@
/**
* 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;
}
}
}

26
commands/indent/proto.h Normal file
View file

@ -0,0 +1,26 @@
/* _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( void 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 ) );