This commit is contained in:
Alexander Popov 2022-09-30 01:01:29 +03:00
parent 58035f08a7
commit 006c3d1501
Signed by: iiiypuk
GPG Key ID: D8C9B59A9F04A70C
10 changed files with 2941 additions and 2816 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
indent indent
*.BAK

485
args.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: args.c,v 1.18 2014/05/20 01:25:23 guenther Exp $ */ /* $OpenBSD: args.c,v 1.18 2014/05/20 01:25:23 guenther Exp $ */
/* /*
* Copyright (c) 1980, 1993 * Copyright (c) 1980, 1993
@ -46,22 +46,22 @@
#include <err.h> #include <err.h>
/* profile types */ /* profile types */
#define PRO_SPECIAL 1 /* special case */ #define PRO_SPECIAL 1 /* special case */
#define PRO_BOOL 2 /* boolean */ #define PRO_BOOL 2 /* boolean */
#define PRO_INT 3 /* integer */ #define PRO_INT 3 /* integer */
#define PRO_FONT 4 /* troff font */ #define PRO_FONT 4 /* troff font */
/* profile specials for booleans */ /* profile specials for booleans */
#define ON 1 /* turn it on */ #define ON 1 /* turn it on */
#define OFF 0 /* turn it off */ #define OFF 0 /* turn it off */
/* profile specials for specials */ /* profile specials for specials */
#define IGN 1 /* ignore it */ #define IGN 1 /* ignore it */
#define CLI 2 /* case label indent (float) */ #define CLI 2 /* case label indent (float) */
#define STDIN 3 /* use stdin */ #define STDIN 3 /* use stdin */
#define KEY 4 /* type (keyword) */ #define KEY 4 /* type (keyword) */
char *option_source = "?"; char *option_source = "?";
/* /*
* N.B.: because of the way the table here is scanned, options whose names are * N.B.: because of the way the table here is scanned, options whose names are
@ -70,88 +70,220 @@ char *option_source = "?";
* default value is the one actually assigned. * default value is the one actually assigned.
*/ */
struct pro { struct pro {
char *p_name; /* name, eg -bl, -cli */ char *p_name; /* name, eg -bl, -cli */
int p_type; /* type (int, bool, special) */ int p_type; /* type (int, bool, special) */
int p_default; /* the default value (if int) */ int p_default; /* the default value (if int) */
int p_special; /* depends on type */ int p_special; /* depends on type */
int *p_obj; /* the associated variable */ int *p_obj; /* the associated variable */
} pro[] = { } pro[] = {
{ "T", PRO_SPECIAL, 0, KEY, 0 }, {
{"bacc", PRO_BOOL, false, ON, "T", PRO_SPECIAL, 0, KEY, 0
&blanklines_around_conditional_compilation }, },
{"badp", PRO_BOOL, false, ON, {
&blanklines_after_declarations_at_proctop }, "bacc", PRO_BOOL, false, ON,
{"bad", PRO_BOOL, false, ON, &blanklines_after_declarations }, &blanklines_around_conditional_compilation
{"bap", PRO_BOOL, false, ON, &blanklines_after_procs }, },
{"bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments }, {
{"bc", PRO_BOOL, true, OFF, &ps.leave_comma }, "badp", PRO_BOOL, false, ON,
{"bl", PRO_BOOL, true, OFF, &btype_2 }, &blanklines_after_declarations_at_proctop
{"br", PRO_BOOL, true, ON, &btype_2 }, },
{"bs", PRO_BOOL, false, ON, &Bill_Shannon }, {
{"cdb", PRO_BOOL, true, ON, &comment_delimiter_on_blankline }, "bad", PRO_BOOL, false, ON, &blanklines_after_declarations
{"cd", PRO_INT, 0, 0, &ps.decl_com_ind }, },
{"ce", PRO_BOOL, true, ON, &cuddle_else }, {
{"ci", PRO_INT, 0, 0, &continuation_indent }, "bap", PRO_BOOL, false, ON, &blanklines_after_procs
{"cli", PRO_SPECIAL, 0, CLI, 0 }, },
{"c", PRO_INT, 33, 0, &ps.com_ind }, {
{"di", PRO_INT, 16, 0, &ps.decl_indent }, "bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments
{"dj", PRO_BOOL, false, ON, &ps.ljust_decl }, },
{"d", PRO_INT, 0, 0, &ps.unindent_displace }, {
{"eei", PRO_BOOL, false, ON, &extra_expression_indent }, "bc", PRO_BOOL, true, OFF, &ps.leave_comma
{"ei", PRO_BOOL, true, ON, &ps.else_if }, },
{"fbc", PRO_FONT, 0, 0, (int *) &blkcomf }, {
{"fbx", PRO_FONT, 0, 0, (int *) &boxcomf }, "bl", PRO_BOOL, true, OFF, &btype_2
{"fb", PRO_FONT, 0, 0, (int *) &bodyf }, },
{"fc1", PRO_BOOL, true, ON, &format_col1_comments }, {
{"fc", PRO_FONT, 0, 0, (int *) &scomf }, "br", PRO_BOOL, true, ON, &btype_2
{"fk", PRO_FONT, 0, 0, (int *) &keywordf }, },
{"fs", PRO_FONT, 0, 0, (int *) &stringf }, {
{"ip", PRO_BOOL, true, ON, &ps.indent_parameters }, "bs", PRO_BOOL, false, ON, &Bill_Shannon
{"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 }, "cdb", PRO_BOOL, true, ON, &comment_delimiter_on_blankline
{"l", PRO_INT, 78, 0, &max_col }, },
{"nbacc", PRO_BOOL, false, OFF, {
&blanklines_around_conditional_compilation }, "cd", PRO_INT, 0, 0, &ps.decl_com_ind
{"nbadp", PRO_BOOL, false, OFF, },
&blanklines_after_declarations_at_proctop }, {
{"nbad", PRO_BOOL, false, OFF, &blanklines_after_declarations }, "ce", PRO_BOOL, true, ON, &cuddle_else
{"nbap", PRO_BOOL, false, OFF, &blanklines_after_procs }, },
{"nbbb", PRO_BOOL, false, OFF, &blanklines_before_blockcomments }, {
{"nbc", PRO_BOOL, true, ON, &ps.leave_comma }, "ci", PRO_INT, 0, 0, &continuation_indent
{"nbs", PRO_BOOL, false, OFF, &Bill_Shannon }, },
{"ncdb", PRO_BOOL, true, OFF, &comment_delimiter_on_blankline }, {
{"nce", PRO_BOOL, true, OFF, &cuddle_else }, "cli", PRO_SPECIAL, 0, CLI, 0
{"ndj", PRO_BOOL, false, OFF, &ps.ljust_decl }, },
{"neei", PRO_BOOL, false, OFF, &extra_expression_indent }, {
{"nei", PRO_BOOL, true, OFF, &ps.else_if }, "c", PRO_INT, 33, 0, &ps.com_ind
{"nfc1", PRO_BOOL, true, OFF, &format_col1_comments }, },
{"nip", PRO_BOOL, true, OFF, &ps.indent_parameters }, {
{"nlp", PRO_BOOL, true, OFF, &lineup_to_parens }, "di", PRO_INT, 16, 0, &ps.decl_indent
{"npcs", PRO_BOOL, false, OFF, &proc_calls_space }, },
{"npro", PRO_SPECIAL, 0, IGN, 0 }, {
{"npsl", PRO_BOOL, true, OFF, &procnames_start_line }, "dj", PRO_BOOL, false, ON, &ps.ljust_decl
{"nps", PRO_BOOL, false, OFF, &pointer_as_binop }, },
{"nsc", PRO_BOOL, true, OFF, &star_comment_cont }, {
{"nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines }, "d", PRO_INT, 0, 0, &ps.unindent_displace
{"nut", PRO_BOOL, true, OFF, &use_tabs}, },
{"nv", PRO_BOOL, false, OFF, &verbose }, {
{"pcs", PRO_BOOL, false, ON, &proc_calls_space }, "eei", PRO_BOOL, false, ON, &extra_expression_indent
{"psl", PRO_BOOL, true, ON, &procnames_start_line }, },
{"ps", PRO_BOOL, false, ON, &pointer_as_binop }, {
{"sc", PRO_BOOL, true, ON, &star_comment_cont }, "ei", PRO_BOOL, true, ON, &ps.else_if
{"sob", PRO_BOOL, false, ON, &swallow_optional_blanklines }, },
{"st", PRO_SPECIAL, 0, STDIN, 0 }, {
{"troff", PRO_BOOL, false, ON, &troff }, "fbc", PRO_FONT, 0, 0, (int *) &blkcomf
{"ut", PRO_BOOL, true, ON, &use_tabs}, },
{"v", PRO_BOOL, false, ON, &verbose }, {
"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
},
{
"nut", PRO_BOOL, true, OFF, &use_tabs
},
{
"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
},
{
"ut", PRO_BOOL, true, ON, &use_tabs
},
{
"v", PRO_BOOL, false, ON, &verbose
},
/* whew! */ /* whew! */
{ 0, 0, 0, 0, 0 } {
0, 0, 0, 0, 0
}
}; };
void scan_profile(FILE *); void scan_profile(FILE *);
void set_option(char *); void set_option(char *);
/* /*
* set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments * set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments
@ -160,64 +292,63 @@ void set_option(char *);
void void
set_profile(void) set_profile(void)
{ {
FILE *f; FILE *f;
char fname[BUFSIZ]; char fname[BUFSIZ];
char *home; char *home;
static char prof[] = ".indent.pro"; static char prof[] = ".indent.pro";
home = getenv("HOME"); home = getenv("HOME");
if (home != NULL && *home != '\0') { if (home != NULL && *home != '\0') {
if (snprintf(fname, sizeof fname, "%s/%s", home, prof) >= sizeof fname) { if (snprintf(fname, sizeof fname, "%s/%s", home, prof) >= sizeof fname) {
#if defined(__linux__) #if defined(__linux__)
printf("%s/%s", home, prof); // FIXIT printf("%s/%s", home, prof);
#else //FIXIT
#else
warnc(ENAMETOOLONG, "%s/%s", home, prof); warnc(ENAMETOOLONG, "%s/%s", home, prof);
#endif #endif
return; return;
} }
if ((f = fopen(option_source = fname, "r")) != NULL) { if ((f = fopen(option_source = fname, "r")) != NULL) {
scan_profile(f); scan_profile(f);
(void) fclose(f); (void) fclose(f);
} }
} }
if ((f = fopen(option_source = prof, "r")) != NULL) { if ((f = fopen(option_source = prof, "r")) != NULL) {
scan_profile(f); scan_profile(f);
(void) fclose(f); (void) fclose(f);
} }
option_source = "Command line"; option_source = "Command line";
} }
void void
scan_profile(FILE *f) scan_profile(FILE * f)
{ {
int i; int i;
char *p; char *p;
char buf[BUFSIZ]; char buf[BUFSIZ];
while (1) { while (1) {
for (p = buf; for (p = buf;
(i = getc(f)) != EOF && (*p = i) > ' ' && p + 1 - buf < BUFSIZ; (i = getc(f)) != EOF && (*p = i) > ' ' && p + 1 - buf < BUFSIZ;
++p) ++p);
; if (p != buf) {
if (p != buf) { *p = 0;
*p = 0; if (verbose)
if (verbose) printf("profile: %s\n", buf);
printf("profile: %s\n", buf); set_option(buf);
set_option(buf); } else if (i == EOF)
} return;
else if (i == EOF)
return;
} }
} }
char *param_start; char *param_start;
int int
eqin(char *s1, char *s2) eqin(char *s1, char *s2)
{ {
while (*s1) { while (*s1) {
if (*s1++ != *s2++) if (*s1++ != *s2++)
return (false); return (false);
} }
param_start = s2; param_start = s2;
return (true); return (true);
@ -229,89 +360,89 @@ eqin(char *s1, char *s2)
void void
set_defaults(void) set_defaults(void)
{ {
struct pro *p; struct pro *p;
/* /*
* Because ps.case_indent is a float, we can't initialize it from the * Because ps.case_indent is a float, we can't initialize it from the
* table: * table:
*/ */
ps.case_indent = 0.0; /* -cli0.0 */ ps.case_indent = 0.0; /* -cli0.0 */
for (p = pro; p->p_name; p++) for (p = pro; p->p_name; p++)
if (p->p_type != PRO_SPECIAL && p->p_type != PRO_FONT) if (p->p_type != PRO_SPECIAL && p->p_type != PRO_FONT)
*p->p_obj = p->p_default; *p->p_obj = p->p_default;
} }
void void
set_option(char *arg) set_option(char *arg)
{ {
struct pro *p; struct pro *p;
arg++; /* ignore leading "-" */ arg++; /* ignore leading "-" */
for (p = pro; p->p_name; p++) for (p = pro; p->p_name; p++)
if (*p->p_name == *arg && eqin(p->p_name, arg)) if (*p->p_name == *arg && eqin(p->p_name, arg))
goto found; goto found;
errx(1, "%s: unknown parameter \"%s\"", option_source, arg - 1); errx(1, "%s: unknown parameter \"%s\"", option_source, arg - 1);
found: found:
switch (p->p_type) { switch (p->p_type) {
case PRO_SPECIAL: case PRO_SPECIAL:
switch (p->p_special) { switch (p->p_special) {
case IGN: case IGN:
break; break;
case CLI: case CLI:
if (*param_start == 0) if (*param_start == 0)
goto need_param; goto need_param;
ps.case_indent = atof(param_start); ps.case_indent = atof(param_start);
break; break;
case STDIN: case STDIN:
if (input == 0) if (input == 0)
input = stdin; input = stdin;
if (output == 0) if (output == 0)
output = stdout; output = stdout;
break; break;
case KEY: case KEY:
if (*param_start == 0) if (*param_start == 0)
goto need_param; goto need_param;
{ {
char *str; char *str;
if ((str = strdup(param_start)) == NULL) if ((str = strdup(param_start)) == NULL)
err(1, NULL); err(1, NULL);
addkey(str, 4); addkey(str, 4);
}
break;
default:
errx(1, "set_option: internal error: p_special %d", p->p_special);
} }
break; break;
default:
errx(1, "set_option: internal error: p_special %d", p->p_special);
}
break;
case PRO_BOOL: case PRO_BOOL:
if (p->p_special == OFF) if (p->p_special == OFF)
*p->p_obj = false; *p->p_obj = false;
else else
*p->p_obj = true; *p->p_obj = true;
break; break;
case PRO_INT: case PRO_INT:
if (!isdigit((unsigned char)*param_start)) { if (!isdigit((unsigned char) *param_start)) {
need_param: need_param:
errx(1, "%s: ``%s'' requires a parameter", option_source, arg - 1); errx(1, "%s: ``%s'' requires a parameter", option_source, arg - 1);
} }
*p->p_obj = atoi(param_start); *p->p_obj = atoi(param_start);
if (*p->p_name == 'i' && *p->p_obj <= 0) if (*p->p_name == 'i' && *p->p_obj <= 0)
errx(1, "%s: ``%s must be greater of zero''", errx(1, "%s: ``%s must be greater of zero''",
option_source, arg - 1); option_source, arg - 1);
break; break;
case PRO_FONT: case PRO_FONT:
parsefont((struct fstate *) p->p_obj, param_start); parsefont((struct fstate *) p->p_obj, param_start);
break; break;
default: default:
errx(1, "set_option: internal error: p_type %d", p->p_type); errx(1, "set_option: internal error: p_type %d", p->p_type);
} }
} }

2192
indent.c

File diff suppressed because it is too large Load Diff

1
indent.txt Normal file
View File

@ -0,0 +1 @@
:indent -nut -i4 -br

View File

@ -1,4 +1,4 @@
/* $OpenBSD: indent_codes.h,v 1.5 2015/01/19 15:30:52 krw Exp $ */ /* $OpenBSD: indent_codes.h,v 1.5 2015/01/19 15:30:52 krw Exp $ */
/* /*
* Copyright (c) 1985 Sun Microsystems, Inc. * Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980, 1993 * Copyright (c) 1980, 1993

View File

@ -1,4 +1,4 @@
/* $OpenBSD: indent_globs.h,v 1.15 2021/01/26 18:21:25 deraadt Exp $ */ /* $OpenBSD: indent_globs.h,v 1.15 2021/01/26 18:21:25 deraadt Exp $ */
/* /*
* Copyright (c) 1985 Sun Microsystems, Inc. * Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980, 1993 * Copyright (c) 1980, 1993
@ -34,22 +34,22 @@
*/ */
#define BACKSLASH '\\' #define BACKSLASH '\\'
#define bufsize 200 /* size of internal buffers */ #define bufsize 200 /* size of internal buffers */
#define sc_size 5000 /* size of save_com buffer */ #define sc_size 5000 /* size of save_com buffer */
#define label_offset 2 /* number of levels a label is placed to left #define label_offset 2 /* number of levels a label is placed to left
* of code */ * of code */
#define tabsize 8 /* the size of a tab */ #define tabsize 8 /* the size of a tab */
#define tabmask 0177770 /* mask used when figuring length of lines #define tabmask 0177770 /* mask used when figuring length of lines
* with tabs */ * with tabs */
#define false 0 #define false 0
#define true 1 #define true 1
extern FILE *input; /* the fid for the input file */ extern FILE *input; /* the fid for the input file */
extern FILE *output; /* the output file */ extern FILE *output; /* the output file */
#define CHECK_SIZE_CODE \ #define CHECK_SIZE_CODE \
if (e_code >= l_code) { \ if (e_code >= l_code) { \
@ -96,248 +96,258 @@ extern FILE *output; /* the output file */
s_token = tokenbuf + 1; \ s_token = tokenbuf + 1; \
} }
extern char *labbuf; /* buffer for label */ extern char *labbuf; /* buffer for label */
extern char *s_lab; /* start ... */ extern char *s_lab; /* start ... */
extern char *e_lab; /* .. and end of stored label */ extern char *e_lab; /* .. and end of stored label */
extern char *l_lab; /* limit of label buffer */ extern char *l_lab; /* limit of label buffer */
extern char *codebuf; /* buffer for code section */ extern char *codebuf; /* buffer for code section */
extern char *s_code; /* start ... */ extern char *s_code; /* start ... */
extern char *e_code; /* .. and end of stored code */ extern char *e_code; /* .. and end of stored code */
extern char *l_code; /* limit of code section */ extern char *l_code; /* limit of code section */
extern char *combuf; /* buffer for comments */ extern char *combuf; /* buffer for comments */
extern char *s_com; /* start ... */ extern char *s_com; /* start ... */
extern char *e_com; /* ... and end of stored comments */ extern char *e_com; /* ... and end of stored comments */
extern char *l_com; /* limit of comment buffer */ extern char *l_com; /* limit of comment buffer */
#define token s_token #define token s_token
extern char *tokenbuf; /* the last token scanned */ extern char *tokenbuf; /* the last token scanned */
extern char *s_token; extern char *s_token;
extern char *e_token; extern char *e_token;
extern char *l_token; extern char *l_token;
extern char *in_buffer; /* input buffer */ extern char *in_buffer; /* input buffer */
extern char *in_buffer_limit; /* the end of the 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 extern char *buf_ptr; /* ptr to next character to be taken from
* in_buffer */ * in_buffer */
extern char *buf_end; /* ptr to first after last char in 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 extern char save_com[sc_size]; /* input text is saved here when
* the brace after an if, while, etc */ * looking for the brace after an if,
extern char *sc_end; /* pointer into save_com buffer */ * while, etc */
extern char *sc_end; /* pointer into save_com buffer */
extern char *bp_save; /* saved value of buf_ptr when taking input extern char *bp_save; /* saved value of buf_ptr when taking input
* from save_com */ * from save_com */
extern char *be_save; /* similarly saved value of buf_end */ extern char *be_save; /* similarly saved value of buf_end */
extern int pointer_as_binop; extern int pointer_as_binop;
extern int blanklines_after_declarations; extern int blanklines_after_declarations;
extern int blanklines_before_blockcomments; extern int blanklines_before_blockcomments;
extern int blanklines_after_procs; extern int blanklines_after_procs;
extern int blanklines_around_conditional_compilation; extern int blanklines_around_conditional_compilation;
extern int swallow_optional_blanklines; extern int swallow_optional_blanklines;
extern int n_real_blanklines; extern int n_real_blanklines;
extern int prefix_blankline_requested; extern int prefix_blankline_requested;
extern int postfix_blankline_requested; extern int postfix_blankline_requested;
extern int break_comma; /* when true and not in parens, break after a extern int break_comma; /* when true and not in parens, break after a
* comma */ * comma */
extern int btype_2; /* when true, brace should be on same line as extern int btype_2; /* when true, brace should be on same line as
* if, while, etc */ * if, while, etc */
extern float case_ind; /* indentation level to be used for a "case extern float case_ind; /* indentation level to be used for a "case
* n:" */ * n:" */
extern int code_lines; /* count of lines with code */ extern int code_lines; /* count of lines with code */
extern int had_eof; /* set to true when input is exhausted */ extern int had_eof; /* set to true when input is exhausted */
extern int line_no; /* the current line number. */ extern int line_no; /* the current line number. */
extern int max_col; /* the maximum allowable line length */ extern int max_col; /* the maximum allowable line length */
extern int verbose; /* when true, non-essential error messages are extern int verbose; /* when true, non-essential error messages
* printed */ * are printed */
extern int cuddle_else; /* true if else should cuddle up to '}' */ extern int cuddle_else; /* true if else should cuddle up to '}' */
extern int star_comment_cont; /* true iff comment continuation lines should extern int star_comment_cont; /* true iff comment continuation
* have stars at the beginning of each line. */ * lines should have stars at the
extern int comment_delimiter_on_blankline; * beginning of each line. */
extern int troff; /* true iff were generating troff input */ extern int comment_delimiter_on_blankline;
extern int procnames_start_line; /* if true, the names of procedures extern int troff; /* true iff were generating troff input */
* being defined get placed in column extern int procnames_start_line; /* if true, the names of procedures
* 1 (ie. a newline is placed between * being defined get placed in column
* the type of the procedure and its * 1 (ie. a newline is placed between
* name) */ * the type of the procedure and its
extern int proc_calls_space; /* If true, procedure calls look like: * name) */
* foo(bar) rather than foo (bar) */ extern int proc_calls_space; /* If true, procedure calls look
extern int format_col1_comments; /* If comments which start in column 1 * like: foo(bar) rather than foo
* are to be magically reformatted * (bar) */
* (just like comments that begin in extern int format_col1_comments; /* If comments which start in column
* later columns) */ * 1 are to be magically reformatted
extern int inhibit_formatting; /* true if INDENT OFF is in effect */ * (just like comments that begin in
extern int suppress_blanklines;/* set iff following blanklines should be * later columns) */
* suppressed */ extern int inhibit_formatting; /* true if INDENT OFF is in effect */
extern int continuation_indent;/* set to the indentation between the edge of extern int suppress_blanklines; /* set iff following blanklines
* code and continuation lines */ * should be suppressed */
extern int lineup_to_parens; /* if true, continued code within parens will extern int continuation_indent; /* set to the indentation between the
* be lined up to the open paren */ * edge of code and continuation
extern int Bill_Shannon; /* true iff a blank should always be inserted * lines */
* after sizeof */ extern int lineup_to_parens; /* if true, continued code within
extern int blanklines_after_declarations_at_proctop; /* This is vaguely * parens will be lined up to the
* similar to * open paren */
* blanklines_after_decla extern int Bill_Shannon; /* true iff a blank should always be inserted
* rations except that * after sizeof */
* it only applies to extern int blanklines_after_declarations_at_proctop; /* This is vaguely
* the first set of * similar to
* declarations in a * blanklines_after_decla
* procedure (just after * rations except that
* the first '{') and it * it only applies to
* causes a blank line * the first set of
* to be generated even * declarations in a
* if there are no * procedure (just after
* declarations */ * the first '{') and it
extern int block_comment_max_col; * causes a blank line
extern int extra_expression_indent; /* True if continuation lines from the * to be generated even
* expression part of "if(e)", * if there are no
* "while(e)", "for(e;e;e)" should be * declarations */
* indented an extra tab stop so that extern int block_comment_max_col;
* they don't conflict with the code extern int extra_expression_indent; /* True if continuation lines
* that follows */ * from the expression part
extern int use_tabs; /* set true to use tabs for spacing, * of "if(e)", "while(e)",
* false uses all spaces */ * "for(e;e;e)" should be
* indented an extra tab stop
* so that they don't
* conflict with the code
* that follows */
extern int use_tabs; /* set true to use tabs for spacing, false
* uses all spaces */
/* -troff font state information */ /* -troff font state information */
struct fstate { struct fstate {
char font[4]; char font[4];
char size; char size;
int allcaps:1; int allcaps:1;
}; };
extern struct fstate extern struct fstate
keywordf, /* keyword font */ keywordf, /* keyword font */
stringf, /* string font */ stringf, /* string font */
boxcomf, /* Box comment font */ boxcomf, /* Box comment font */
blkcomf, /* Block comment font */ blkcomf, /* Block comment font */
scomf, /* Same line comment font */ scomf, /* Same line comment font */
bodyf; /* major body font */ bodyf; /* major body font */
#define STACKSIZE 150 #define STACKSIZE 150
extern struct parser_state { extern struct parser_state {
int last_token; int last_token;
struct fstate cfont; /* Current font */ struct fstate cfont; /* Current font */
int p_stack[STACKSIZE]; /* this is the parsers stack */ int p_stack[STACKSIZE]; /* this is the parsers stack */
int il[STACKSIZE]; /* this stack stores indentation levels */ int il[STACKSIZE]; /* this stack stores indentation
float cstk[STACKSIZE];/* used to store case stmt indentation levels */ * levels */
int box_com; /* set to true when we are in a "boxed" float cstk[STACKSIZE]; /* used to store case stmt
* comment. In that case, the first non-blank * indentation levels */
* char should be lined up with the / in rem */ int box_com; /* set to true when we are in a "boxed"
int comment_delta, * comment. In that case, the first non-blank
n_comment_delta; * char should be lined up with the / in rem */
int cast_mask; /* indicates which close parens close off int comment_delta, n_comment_delta;
* casts */ int cast_mask; /* indicates which close parens close off
int sizeof_mask; /* indicates which close parens close off * casts */
* sizeof''s */ int sizeof_mask;/* indicates which close parens close off
int block_init; /* true iff inside a block initialization */ * sizeof''s */
int block_init_level; /* The level of brace nesting in an int block_init; /* true iff inside a block initialization */
* initialization */ int block_init_level; /* The level of brace nesting in an
int last_nl; /* this is true if the last thing scanned was * initialization */
* a newline */ int last_nl; /* this is true if the last thing scanned was
int in_or_st; /* Will be true iff there has been a * a newline */
* declarator (e.g. int or char) and no left int in_or_st; /* Will be true iff there has been a
* paren since the last semicolon. When true, * declarator (e.g. int or char) and no left
* a '{' is starting a structure definition or * paren since the last semicolon. When true,
* an initialization list */ * a '{' is starting a structure definition
int bl_line; /* set to 1 by dump_line if the line is blank */ * or an initialization list */
int col_1; /* set to true if the last token started in int bl_line; /* set to 1 by dump_line if the line is blank */
* column 1 */ int col_1; /* set to true if the last token started in
int com_col; /* this is the column in which the current * column 1 */
* coment should start */ int com_col; /* this is the column in which the current
int com_ind; /* the column in which comments to the right * coment should start */
* of code should start */ int com_ind; /* the column in which comments to the right
int com_lines; /* the number of lines with comments, set by * of code should start */
* dump_line */ int com_lines; /* the number of lines with comments, set by
int dec_nest; /* current nesting level for structure or init */ * dump_line */
int decl_com_ind; /* the column in which comments after int dec_nest; /* current nesting level for structure or
* declarations should be put */ * init */
int decl_on_line; /* set to true if this line of code has part int decl_com_ind; /* the column in which comments after
* of a declaration on it */ * declarations should be put */
int i_l_follow; /* the level to which ind_level should be set int decl_on_line; /* set to true if this line of code
* after the current line is printed */ * has part of a declaration on it */
int in_decl; /* set to true when we are in a declaration int i_l_follow; /* the level to which ind_level should be set
* stmt. The processing of braces is then * after the current line is printed */
* slightly different */ int in_decl; /* set to true when we are in a declaration
int in_stmt; /* set to 1 while in a stmt */ * stmt. The processing of braces is then
int ind_level; /* the current indentation level */ * slightly different */
int ind_size; /* the size of one indentation level */ int in_stmt; /* set to 1 while in a stmt */
int ind_stmt; /* set to 1 if next line should have an extra int ind_level; /* the current indentation level */
* indentation level because we are in the int ind_size; /* the size of one indentation level */
* middle of a stmt */ int ind_stmt; /* set to 1 if next line should have an extra
int last_u_d; /* set to true after scanning a token which * indentation level because we are in the
* forces a following operator to be unary */ * middle of a stmt */
int leave_comma; /* if true, never break declarations after int last_u_d; /* set to true after scanning a token which
* commas */ * forces a following operator to be unary */
int ljust_decl; /* true if declarations should be left int leave_comma;/* if true, never break declarations after
* justified */ * commas */
int out_coms; /* the number of comments processed, set by int ljust_decl; /* true if declarations should be left
* pr_comment */ * justified */
int out_lines; /* the number of lines written, set by int out_coms; /* the number of comments processed, set by
* dump_line */ * pr_comment */
int p_l_follow; /* used to remember how to indent following int out_lines; /* the number of lines written, set by
* statement */ * dump_line */
int paren_level; /* parenthesization level. used to indent int p_l_follow; /* used to remember how to indent following
* within stmts */ * statement */
short paren_indents[20]; /* column positions of each paren */ int paren_level;/* parenthesization level. used to indent
int pcase; /* set to 1 if the current line label is a * within stmts */
* case. It is printed differently from a short paren_indents[20]; /* column positions of each paren */
* regular label */ int pcase; /* set to 1 if the current line label is a
int search_brace; /* set to true by parse when it is necessary * case. It is printed differently from a
* to buffer up all info up to the start of a * regular label */
* stmt after an if, while, etc */ int search_brace; /* set to true by parse when it is
int unindent_displace; /* comments not to the right of code * necessary to buffer up all info up
* will be placed this many * to the start of a stmt after an
* indentation levels to the left of * if, while, etc */
* code */ int unindent_displace; /* comments not to the right of code
int use_ff; /* set to one if the current line should be * will be placed this many
* terminated with a form feed */ * indentation levels to the left of
int want_blank; /* set to true when the following token should * code */
* be prefixed by a blank. (Said prefixing is int use_ff; /* set to one if the current line should be
* ignored in some cases.) */ * terminated with a form feed */
int else_if; /* True iff else if pairs should be handled int want_blank; /* set to true when the following token
* specially */ * should be prefixed by a blank. (Said
int decl_indent; /* column to indent declared identifiers to */ * prefixing is ignored in some cases.) */
int its_a_keyword; int else_if; /* True iff else if pairs should be handled
int sizeof_keyword; * specially */
int dumped_decl_indent; int decl_indent;/* column to indent declared identifiers to */
float case_indent; /* The distance to indent case labels from the int its_a_keyword;
* switch statement */ int sizeof_keyword;
int in_parameter_declaration; int dumped_decl_indent;
int indent_parameters; float case_indent;/* The distance to indent case labels from
int tos; /* pointer to top of stack */ * the switch statement */
char procname[100]; /* The name of the current procedure */ int in_parameter_declaration;
int just_saw_decl; int indent_parameters;
} ps; 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 ifdef_level;
extern int rparen_count; extern int rparen_count;
extern struct parser_state state_stack[5]; extern struct parser_state state_stack[5];
extern struct parser_state match_state[5]; extern struct parser_state match_state[5];
int compute_code_target(void); int compute_code_target(void);
int compute_label_target(void); int compute_label_target(void);
int count_spaces(int, char *); int count_spaces(int, char *);
void diag(int, const char *, ...) __attribute__((__format__ (printf, 2, 3))); void diag(int, const char *,...) __attribute__((__format__(printf, 2, 3)));
void dump_line(void); void dump_line(void);
int eqin(char *, char *); int eqin(char *, char *);
void fill_buffer(void); void fill_buffer(void);
int pad_output(int, int); int pad_output(int, int);
void scan_profile(FILE *); void scan_profile(FILE *);
void set_defaults(void); void set_defaults(void);
void set_option(char *); void set_option(char *);
void addkey(char *, int); void addkey(char *, int);
void set_profile(void); void set_profile(void);
char *chfont(struct fstate *, struct fstate *, char *); char *chfont(struct fstate *, struct fstate *, char *);
void parsefont(struct fstate *, char *); void parsefont(struct fstate *, char *);
void writefdef(struct fstate *, int); void writefdef(struct fstate *, int);
int lexi(void); int lexi(void);
void reduce(void); void reduce(void);
void parse(int); void parse(int);
void pr_comment(void); void pr_comment(void);
void bakcopy(void); void bakcopy(void);

759
io.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: io.c,v 1.14 2015/09/27 17:00:46 guenther Exp $ */ /* $OpenBSD: io.c,v 1.14 2015/09/27 17:00:46 guenther Exp $ */
/* /*
* Copyright (c) 1985 Sun Microsystems, Inc. * Copyright (c) 1985 Sun Microsystems, Inc.
@ -40,231 +40,228 @@
#include "indent_globs.h" #include "indent_globs.h"
int comment_open; int comment_open;
static int paren_target; static int paren_target;
void void
dump_line(void) dump_line(void)
{ /* dump_line is the routine that actually { /* dump_line is the routine that actually
* effects the printing of the new source. It * effects the printing of the new source. It
* prints the label section, followed by the * prints the label section, followed by the
* code section with the appropriate nesting * code section with the appropriate nesting
* level, followed by any comments */ * level, followed by any comments */
int cur_col, target_col; int cur_col, target_col;
static int not_first_line; static int not_first_line;
if (ps.procname[0]) { if (ps.procname[0]) {
if (troff) { if (troff) {
if (comment_open) { if (comment_open) {
comment_open = 0; comment_open = 0;
fprintf(output, ".*/\n"); fprintf(output, ".*/\n");
}
fprintf(output, ".Pr \"%s\"\n", ps.procname);
} }
fprintf(output, ".Pr \"%s\"\n", ps.procname); ps.ind_level = 0;
} ps.procname[0] = 0;
ps.ind_level = 0;
ps.procname[0] = 0;
} }
if (s_code == e_code && s_lab == e_lab && s_com == e_com) { if (s_code == e_code && s_lab == e_lab && s_com == e_com) {
if (suppress_blanklines > 0) if (suppress_blanklines > 0)
suppress_blanklines--; suppress_blanklines--;
else { else {
ps.bl_line = true; ps.bl_line = true;
n_real_blanklines++; 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;
} }
} } else if (!inhibit_formatting) {
while (--n_real_blanklines >= 0) suppress_blanklines = 0;
putc('\n', output); ps.bl_line = false;
n_real_blanklines = 0; if (prefix_blankline_requested && not_first_line) {
if (ps.ind_level == 0) if (swallow_optional_blanklines) {
ps.ind_stmt = 0; /* this is a class A kludge. dont do if (n_real_blanklines == 1)
* additional statement indentation if we are n_real_blanklines = 0;
* at bracket level 0 */ } else {
if (n_real_blanklines == 0)
if (e_lab != s_lab || e_code != s_code) n_real_blanklines = 1;
++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 (--n_real_blanklines >= 0)
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); putc('\n', output);
cur_col = 1; n_real_blanklines = 0;
++ps.out_lines; 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);
} }
while (e_com > com_st && isspace((unsigned char)e_com[-1])) if (s_com != e_com) {
e_com--; if (troff) {
cur_col = pad_output(cur_col, target); int all_here = 0;
if (!ps.box_com) { char *p;
if (star_comment_cont && (com_st[1] != '*' || e_com <= com_st + 1)) {
if (com_st[1] == ' ' && com_st[0] == ' ' && e_com > com_st + 1) if (e_com[-1] == '/' && e_com[-2] == '*')
com_st[1] = '*'; e_com -= 2, all_here++;
else while (e_com > s_com && e_com[-1] == ' ')
fwrite(" * ", com_st[0] == '\t' ? 2 : com_st[0] == '*' ? 1 : 3, 1, output); 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 */
} }
} }
fwrite(com_st, e_com - com_st, 1, output); if (ps.use_ff)
ps.comment_delta = ps.n_comment_delta; putc('\014', output);
cur_col = count_spaces(cur_col, com_st); else
++ps.com_lines; /* count lines with comments */ putc('\n', output);
}
}
if (ps.use_ff)
putc('\014', output);
else
putc('\n', output);
inhibit_newline: inhibit_newline:
++ps.out_lines; ++ps.out_lines;
if (ps.just_saw_decl == 1 && blanklines_after_declarations) { if (ps.just_saw_decl == 1 && blanklines_after_declarations) {
prefix_blankline_requested = 1; prefix_blankline_requested = 1;
ps.just_saw_decl = 0; ps.just_saw_decl = 0;
} else
prefix_blankline_requested = postfix_blankline_requested;
postfix_blankline_requested = 0;
} }
else ps.decl_on_line = ps.in_decl; /* if we are in the middle of a
prefix_blankline_requested = postfix_blankline_requested; * declaration, remember that fact
postfix_blankline_requested = 0; * for proper comment indentation */
} ps.ind_stmt = ps.in_stmt & ~ps.in_decl; /* next line should be
ps.decl_on_line = ps.in_decl; /* if we are in the middle of a * indented if we have not
* declaration, remember that fact for * completed this stmt and if
* proper comment indentation */ * we are not in the middle
ps.ind_stmt = ps.in_stmt & ~ps.in_decl; /* next line should be * of a declaration */
* indented if we have not
* completed this stmt and if
* we are not in the middle of
* a declaration */
ps.use_ff = false; ps.use_ff = false;
ps.dumped_decl_indent = 0; ps.dumped_decl_indent = 0;
*(e_lab = s_lab) = '\0'; /* reset buffers */ *(e_lab = s_lab) = '\0'; /* reset buffers */
@ -280,27 +277,26 @@ inhibit_newline:
int int
compute_code_target(void) compute_code_target(void)
{ {
int target_col; int target_col;
target_col = ps.ind_size * ps.ind_level + 1; target_col = ps.ind_size * ps.ind_level + 1;
if (ps.paren_level) if (ps.paren_level)
if (!lineup_to_parens) if (!lineup_to_parens)
target_col += continuation_indent * ps.paren_level; target_col += continuation_indent * ps.paren_level;
else { else {
int w; int w;
int t = paren_target; int t = paren_target;
if ((w = count_spaces(t, s_code) - max_col) > 0 if ((w = count_spaces(t, s_code) - max_col) > 0
&& count_spaces(target_col, s_code) <= max_col) { && count_spaces(target_col, s_code) <= max_col) {
t -= w + 1; t -= w + 1;
if (t > target_col) if (t > target_col)
target_col = t; target_col = t;
} else
target_col = t;
} }
else
target_col = t;
}
else if (ps.ind_stmt) else if (ps.ind_stmt)
target_col += continuation_indent; target_col += continuation_indent;
return target_col; return target_col;
} }
@ -331,89 +327,89 @@ compute_label_target(void)
*/ */
void void
fill_buffer(void) fill_buffer(void)
{ /* this routine reads stuff from the input */ { /* this routine reads stuff from the input */
char *p, *buf2; char *p, *buf2;
int i; int i;
FILE *f = input; FILE *f = input;
if (bp_save != 0) { /* there is a partly filled input buffer left */ if (bp_save != 0) { /* there is a partly filled input buffer left */
buf_ptr = bp_save; /* dont read anything, just switch buffers */ buf_ptr = bp_save; /* dont read anything, just switch buffers */
buf_end = be_save; buf_end = be_save;
bp_save = be_save = 0; bp_save = be_save = 0;
if (buf_ptr < buf_end) if (buf_ptr < buf_end)
return; /* only return if there is really something in return; /* only return if there is really something
* this buffer */ * in this buffer */
} }
for (p = in_buffer;;) { for (p = in_buffer;;) {
if (p >= in_buffer_limit) { if (p >= in_buffer_limit) {
int size = (in_buffer_limit - in_buffer) * 2 + 10; int size = (in_buffer_limit - in_buffer) * 2 + 10;
int offset = p - in_buffer; int offset = p - in_buffer;
buf2 = realloc(in_buffer, size); buf2 = realloc(in_buffer, size);
if (buf2 == NULL) if (buf2 == NULL)
errx(1, "input line too long"); errx(1, "input line too long");
in_buffer = buf2; in_buffer = buf2;
p = in_buffer + offset; p = in_buffer + offset;
in_buffer_limit = in_buffer + size - 2; in_buffer_limit = in_buffer + size - 2;
} }
if ((i = getc(f)) == EOF) { if ((i = getc(f)) == EOF) {
*p++ = ' '; *p++ = ' ';
*p++ = '\n'; *p++ = '\n';
had_eof = true; had_eof = true;
break; break;
} }
*p++ = i; *p++ = i;
if (i == '\n') if (i == '\n')
break; break;
} }
buf_ptr = in_buffer; buf_ptr = in_buffer;
buf_end = p; buf_end = p;
if (p - 3 >= in_buffer && p[-2] == '/' && p[-3] == '*') { if (p - 3 >= in_buffer && p[-2] == '/' && p[-3] == '*') {
if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0) if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0)
fill_buffer(); /* flush indent error message */ fill_buffer(); /* flush indent error message */
else { else {
int com = 0; int com = 0;
p = in_buffer; 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') while (*p == ' ' || *p == '\t')
p++; p++;
if (*p == '*') if (*p == '/' && p[1] == '*') {
com = 1; p += 2;
else if (*p == 'O') { while (*p == ' ' || *p == '\t')
if (*++p == 'N') p++;
p++, com = 1; if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E'
else if (*p == 'F' && *++p == 'F') && p[4] == 'N' && p[5] == 'T') {
p++, com = 2; p += 6;
} while (*p == ' ' || *p == '\t')
while (*p == ' ' || *p == '\t') p++;
p++; if (*p == '*')
if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com) { com = 1;
if (s_com != e_com || s_lab != e_lab || s_code != e_code) else if (*p == 'O') {
dump_line(); if (*++p == 'N')
if (!(inhibit_formatting = com - 1)) { p++, com = 1;
n_real_blanklines = 0; else if (*p == 'F' && *++p == 'F')
postfix_blankline_requested = 0; p++, com = 2;
prefix_blankline_requested = 0; }
suppress_blanklines = 1; 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) { if (inhibit_formatting) {
p = in_buffer; p = in_buffer;
do do
putc(*p, output); putc(*p, output);
while (*p++ != '\n'); while (*p++ != '\n');
} }
return; return;
} }
@ -449,23 +445,23 @@ fill_buffer(void)
int int
pad_output(int current, int target) pad_output(int current, int target)
{ {
int curr; /* internal column pointer */ int curr; /* internal column pointer */
int tcur; int tcur;
if (troff) if (troff)
fprintf(output, "\\h'|%dp'", (target - 1) * 7); fprintf(output, "\\h'|%dp'", (target - 1) * 7);
else { else {
if (current >= target) if (current >= target)
return (current); /* line is already long enough */ return (current); /* line is already long enough */
curr = current; curr = current;
if (use_tabs) { if (use_tabs) {
while ((tcur = ((curr - 1) & tabmask) + tabsize + 1) <= target) { while ((tcur = ((curr - 1) & tabmask) + tabsize + 1) <= target) {
putc('\t', output); putc('\t', output);
curr = tcur; curr = tcur;
}
} }
} while (curr++ < target)
while (curr++ < target) putc(' ', output); /* pad with final blanks */
putc(' ', output); /* pad with final blanks */
} }
return (target); return (target);
} }
@ -493,127 +489,124 @@ pad_output(int current, int target)
int int
count_spaces(int current, char *buffer) count_spaces(int current, char *buffer)
{ {
char *buf; /* used to look thru buffer */ char *buf; /* used to look thru buffer */
int cur; /* current character counter */ int cur; /* current character counter */
cur = current; cur = current;
for (buf = buffer; *buf != '\0'; ++buf) { for (buf = buffer; *buf != '\0'; ++buf) {
switch (*buf) { switch (*buf) {
case '\n': case '\n':
case 014: /* form feed */ case 014: /* form feed */
cur = 1; cur = 1;
break; break;
case '\t': case '\t':
cur = ((cur - 1) & tabmask) + tabsize + 1; cur = ((cur - 1) & tabmask) + tabsize + 1;
break; break;
case 010: /* backspace */ case 010: /* backspace */
--cur; --cur;
break; break;
default: default:
++cur; ++cur;
break; break;
} /* end of switch */ } /* end of switch */
} /* end of for loop */ } /* end of for loop */
return (cur); return (cur);
} }
int found_err; int found_err;
void void
diag(int level, const char *msg, ...) diag(int level, const char *msg,...)
{ {
va_list ap; va_list ap;
va_start(ap, msg); va_start(ap, msg);
if (level) if (level)
found_err = 1; found_err = 1;
if (output == stdout) { if (output == stdout) {
fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no); fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no);
vfprintf(stdout, msg, ap); vfprintf(stdout, msg, ap);
fprintf(stdout, " */\n"); fprintf(stdout, " */\n");
} } else {
else { fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no);
fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no); vfprintf(stderr, msg, ap);
vfprintf(stderr, msg, ap); fprintf(stderr, "\n");
fprintf(stderr, "\n");
} }
va_end(ap); va_end(ap);
} }
void void
writefdef(struct fstate *f, int nm) writefdef(struct fstate * f, int nm)
{ {
fprintf(output, ".ds f%c %s\n.nr s%c %d\n", fprintf(output, ".ds f%c %s\n.nr s%c %d\n",
nm, f->font, nm, f->size); nm, f->font, nm, f->size);
} }
char * char *
chfont(struct fstate *of, struct fstate *nf, char *s) chfont(struct fstate * of, struct fstate * nf, char *s)
{ {
if (of->font[0] != nf->font[0] if (of->font[0] != nf->font[0]
|| of->font[1] != nf->font[1]) { || of->font[1] != nf->font[1]) {
*s++ = '\\'; *s++ = '\\';
*s++ = 'f'; *s++ = 'f';
if (nf->font[1]) { if (nf->font[1]) {
*s++ = '('; *s++ = '(';
*s++ = nf->font[0]; *s++ = nf->font[0];
*s++ = nf->font[1]; *s++ = nf->font[1];
} } else
else *s++ = nf->font[0];
*s++ = nf->font[0];
} }
if (nf->size != of->size) { if (nf->size != of->size) {
*s++ = '\\'; *s++ = '\\';
*s++ = 's'; *s++ = 's';
if (nf->size < of->size) { if (nf->size < of->size) {
*s++ = '-'; *s++ = '-';
*s++ = '0' + of->size - nf->size; *s++ = '0' + of->size - nf->size;
} } else {
else { *s++ = '+';
*s++ = '+'; *s++ = '0' + nf->size - of->size;
*s++ = '0' + nf->size - of->size; }
}
} }
return s; return s;
} }
void void
parsefont(struct fstate *f, char *s0) parsefont(struct fstate * f, char *s0)
{ {
char *s = s0; char *s = s0;
int sizedelta = 0; int sizedelta = 0;
bzero(f, sizeof *f); bzero(f, sizeof *f);
while (*s) { while (*s) {
if (isdigit((unsigned char)*s)) if (isdigit((unsigned char) *s))
f->size = f->size * 10 + *s - '0'; f->size = f->size * 10 + *s - '0';
else if (isupper((unsigned char)*s)) else if (isupper((unsigned char) *s))
if (f->font[0]) if (f->font[0])
f->font[1] = *s; 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 else
f->font[0] = *s; errx(1, "bad font specification: %s", s0);
else if (*s == 'c') s++;
f->allcaps = 1;
else if (*s == '+')
sizedelta++;
else if (*s == '-')
sizedelta--;
else
errx(1, "bad font specification: %s", s0);
s++;
} }
if (f->font[0] == 0) if (f->font[0] == 0)
f->font[0] = 'R'; f->font[0] = 'R';
if (bodyf.size == 0) if (bodyf.size == 0)
bodyf.size = 11; bodyf.size = 11;
if (f->size == 0) if (f->size == 0)
f->size = bodyf.size + sizedelta; f->size = bodyf.size + sizedelta;
else if (sizedelta > 0) else if (sizedelta > 0)
f->size += bodyf.size; f->size += bodyf.size;
else else
f->size = bodyf.size - f->size; f->size = bodyf.size - f->size;
} }

837
lexi.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: lexi.c,v 1.20 2016/06/06 06:43:03 tobiasu Exp $ */ /* $OpenBSD: lexi.c,v 1.20 2016/06/06 06:43:03 tobiasu Exp $ */
/* /*
* Copyright (c) 1980, 1993 * Copyright (c) 1980, 1993
@ -50,49 +50,49 @@
#define opchar 3 #define opchar 3
struct templ { struct templ {
char *rwd; char *rwd;
int rwcode; int rwcode;
}; };
struct templ specialsinit[] = { struct templ specialsinit[] = {
{ "switch", 1 }, {"switch", 1},
{ "case", 2 }, {"case", 2},
{ "break", 0 }, {"break", 0},
{ "struct", 3 }, {"struct", 3},
{ "union", 3 }, {"union", 3},
{ "enum", 3 }, {"enum", 3},
{ "default", 2 }, {"default", 2},
{ "int", 4 }, {"int", 4},
{ "char", 4 }, {"char", 4},
{ "float", 4 }, {"float", 4},
{ "double", 4 }, {"double", 4},
{ "long", 4 }, {"long", 4},
{ "short", 4 }, {"short", 4},
{ "typedef", 4 }, {"typedef", 4},
{ "unsigned", 4 }, {"unsigned", 4},
{ "register", 4 }, {"register", 4},
{ "static", 4 }, {"static", 4},
{ "global", 4 }, {"global", 4},
{ "extern", 4 }, {"extern", 4},
{ "void", 4 }, {"void", 4},
{ "goto", 0 }, {"goto", 0},
{ "return", 0 }, {"return", 0},
{ "if", 5 }, {"if", 5},
{ "while", 5 }, {"while", 5},
{ "for", 5 }, {"for", 5},
{ "else", 6 }, {"else", 6},
{ "do", 6 }, {"do", 6},
{ "sizeof", 7 }, {"sizeof", 7},
}; };
struct templ *specials = specialsinit; struct templ *specials = specialsinit;
int nspecials = sizeof(specialsinit) / sizeof(specialsinit[0]); int nspecials = sizeof(specialsinit) / sizeof(specialsinit[0]);
int maxspecials; int maxspecials;
char chartype[128] = char chartype[128] =
{ /* this is used to facilitate the decision of { /* this is used to facilitate the decision of
* what type (alphanumeric, operator) each * what type (alphanumeric, operator) each
* character is */ * 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -117,448 +117,442 @@ char chartype[128] =
int int
lexi(void) lexi(void)
{ {
int unary_delim; /* this is set to 1 if the current token int unary_delim;/* this is set to 1 if the current token
* forces a following operator to be unary */ * forces a following operator to be unary */
static int last_code; /* the last token type returned */ static int last_code; /* the last token type returned */
static int l_struct; /* set to 1 if the last token was 'struct' */ static int l_struct; /* set to 1 if the last token was 'struct' */
int code; /* internal code to be returned */ int code; /* internal code to be returned */
char qchar; /* the delimiter character for a string */ char qchar; /* the delimiter character for a string */
int i; int i;
e_token = s_token; /* point to start of place to save token */ e_token = s_token; /* point to start of place to save token */
unary_delim = false; unary_delim = false;
ps.col_1 = ps.last_nl; /* tell world that this token started in ps.col_1 = ps.last_nl; /* tell world that this token started in
* column 1 iff the last thing scanned was nl */ * column 1 iff the last thing scanned was nl */
ps.last_nl = false; ps.last_nl = false;
while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */ while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */
ps.col_1 = false; /* leading blanks imply token is not in column ps.col_1 = false; /* leading blanks imply token is not in
* 1 */ * column 1 */
if (++buf_ptr >= buf_end) if (++buf_ptr >= buf_end)
fill_buffer(); fill_buffer();
} }
/* Scan an alphanumeric token */ /* Scan an alphanumeric token */
if (chartype[(int)*buf_ptr] == alphanum || if (chartype[(int) *buf_ptr] == alphanum ||
(buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) { (buf_ptr[0] == '.' && isdigit((unsigned char) buf_ptr[1]))) {
/* /*
* we have a character or number * we have a character or number
*/ */
char *j; /* used for searching thru list of char *j; /* used for searching thru list of reserved
* reserved words */ * words */
if (isdigit((unsigned char)*buf_ptr) || if (isdigit((unsigned char) *buf_ptr) ||
(buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) { (buf_ptr[0] == '.' && isdigit((unsigned char) buf_ptr[1]))) {
int seendot = 0, int seendot = 0, seenexp = 0, seensfx = 0;
seenexp = 0, if (*buf_ptr == '0' &&
seensfx = 0; (buf_ptr[1] == 'x' || buf_ptr[1] == 'X')) {
if (*buf_ptr == '0' && *e_token++ = *buf_ptr++;
(buf_ptr[1] == 'x' || buf_ptr[1] == 'X')) { *e_token++ = *buf_ptr++;
*e_token++ = *buf_ptr++; while (isxdigit(*buf_ptr)) {
*e_token++ = *buf_ptr++; CHECK_SIZE_TOKEN;
while (isxdigit(*buf_ptr)) { *e_token++ = *buf_ptr++;
CHECK_SIZE_TOKEN; }
*e_token++ = *buf_ptr++; } else
} while (1) {
} if (*buf_ptr == '.') {
else if (seendot)
while (1) { break;
if (*buf_ptr == '.') { else
if (seendot) 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++;
}
}
}
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; break;
else
seendot++;
} }
CHECK_SIZE_TOKEN; if (!(seensfx & 1) &&
*e_token++ = *buf_ptr++; (*buf_ptr == 'F' || *buf_ptr == 'f')) {
if (!isdigit((unsigned char)*buf_ptr) && *buf_ptr != '.') {
if ((*buf_ptr != 'E' && *buf_ptr != 'e') || seenexp)
break;
else {
seenexp++;
seendot++;
CHECK_SIZE_TOKEN; CHECK_SIZE_TOKEN;
*e_token++ = *buf_ptr++; *e_token++ = *buf_ptr++;
if (*buf_ptr == '+' || *buf_ptr == '-') seensfx |= 1;
*e_token++ = *buf_ptr++;
} }
} } else
} while (chartype[(int) *buf_ptr] == alphanum) { /* copy it over */
while (1) { CHECK_SIZE_TOKEN;
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++;
*e_token++ = *buf_ptr++; if (buf_ptr >= buf_end)
seensfx |= 2; fill_buffer();
continue; }
*e_token++ = '\0';
while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */
if (++buf_ptr >= buf_end)
fill_buffer();
} }
break; 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);
} }
if (!(seensfx & 1) && ps.last_u_d = false; /* Operator after identifier is binary */
(*buf_ptr == 'F' || *buf_ptr == 'f')) { last_code = ident; /* Remember that this is the code we will
CHECK_SIZE_TOKEN; * return */
*e_token++ = *buf_ptr++;
seensfx |= 1;
}
}
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 identifier 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 (i = 0; i < nspecials; i++) {
char *p = s_token; /* point at scanned token */
j = specials[i].rwd;
if (*j++ != *p++ || *j++ != *p++)
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 (p[-1] == 0)
break; /* If its a one-character identifier */
while (*p++ == *j)
if (*j++ == 0)
goto found_keyword; /* I wish that C had a multi-level
* break... */
}
if (i < nspecials) { /* we have a keyword */
found_keyword:
ps.its_a_keyword = true;
ps.last_u_d = true;
switch (specials[i].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 * This loop will check if the token is a keyword.
* 'struct'
*/ */
case 4: /* one of the declaration keywords */ for (i = 0; i < nspecials; i++) {
if (ps.p_l_follow) { char *p = s_token; /* point at scanned token */
ps.cast_mask |= 1 << ps.p_l_follow; j = specials[i].rwd;
break; /* inside parens: cast */ if (*j++ != *p++ || *j++ != *p++)
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 (p[-1] == 0)
break; /* If its a one-character identifier */
while (*p++ == *j)
if (*j++ == 0)
goto found_keyword; /* I wish that C had a multi-level
* break... */
} }
last_code = decl; if (i < nspecials) { /* we have a keyword */
return (decl); found_keyword:
ps.its_a_keyword = true;
ps.last_u_d = true;
switch (specials[i].rwcode) {
case 1: /* it is a switch */
return (swstmt);
case 2: /* a case or default */
return (casestmt);
case 5: /* if, while, for */ case 3: /* a "struct" */
return (sp_paren); if (ps.p_l_follow)
break; /* inside parens: cast */
l_struct = true;
case 6: /* do, else */ /*
return (sp_nparen); * 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 7: case 5: /* if, while, for */
ps.sizeof_keyword = true; return (sp_paren);
default: /* all others are treated like any other
* identifier */ case 6: /* do, else */
return (ident); return (sp_nparen);
} /* end of switch */
} /* end of if (found_it) */ case 7:
if (*buf_ptr == '(' && ps.tos <= 1 && ps.ind_level == 0) { ps.sizeof_keyword = true;
char *tp = buf_ptr; default: /* all others are treated like any other
while (tp < buf_end) * identifier */
if (*tp++ == ')' && (*tp == ';' || *tp == ',')) return (ident);
goto not_proc; } /* end of switch */
strncpy(ps.procname, token, sizeof ps.procname); } /* end of if (found_it) */
// strlcpy(ps.procname, token, sizeof ps.procname); if (*buf_ptr == '(' && ps.tos <= 1 && ps.ind_level == 0) {
ps.in_parameter_declaration = 1; char *tp = buf_ptr;
rparen_count = 1; while (tp < buf_end)
if (*tp++ == ')' && (*tp == ';' || *tp == ','))
goto not_proc;
strncpy(ps.procname, token, sizeof ps.procname);
//strlcpy(ps.procname, token, sizeof ps.procname);
ps.in_parameter_declaration = 1;
rparen_count = 1;
not_proc:; not_proc:;
} }
/* /*
* The following hack attempts to guess whether or not the current * The following hack attempts to guess whether or not the current
* token is in fact a declaration keyword -- one that has been * token is in fact a declaration keyword -- one that has been
* typedefd * typedefd
*/ */
if (((*buf_ptr == '*' && buf_ptr[1] != '=') || if (((*buf_ptr == '*' && buf_ptr[1] != '=') ||
isalpha((unsigned char)*buf_ptr) || *buf_ptr == '_') isalpha((unsigned char) *buf_ptr) || *buf_ptr == '_')
&& !ps.p_l_follow && !ps.p_l_follow
&& !ps.block_init && !ps.block_init
&& (ps.last_token == rparen || ps.last_token == semicolon || && (ps.last_token == rparen || ps.last_token == semicolon ||
ps.last_token == decl || ps.last_token == decl ||
ps.last_token == lbrace || ps.last_token == rbrace)) { ps.last_token == lbrace || ps.last_token == rbrace)) {
ps.its_a_keyword = true; ps.its_a_keyword = true;
ps.last_u_d = true; ps.last_u_d = true;
last_code = decl; last_code = decl;
return decl; return decl;
} }
if (last_code == decl) /* if this is a declared variable, then if (last_code == decl) /* if this is a declared variable, then
* following sign is unary */ * following sign is unary */
ps.last_u_d = true; /* will make "int a -1" work */ ps.last_u_d = true; /* will make "int a -1" work */
last_code = ident; last_code = ident;
return (ident); /* the ident is not in the list */ return (ident); /* the ident is not in the list */
} /* end of procesing for alpanum character */ } /* end of procesing for alpanum character */
/* Scan a non-alphanumeric token */ /* Scan a non-alphanumeric token */
*e_token++ = *buf_ptr; /* if it is only a one-character token, it is *e_token++ = *buf_ptr; /* if it is only a one-character token, it is
* moved here */ * moved here */
*e_token = '\0'; *e_token = '\0';
if (++buf_ptr >= buf_end) if (++buf_ptr >= buf_end)
fill_buffer(); fill_buffer();
switch (*token) { switch (*token) {
case '\n': case '\n':
unary_delim = ps.last_u_d; unary_delim = ps.last_u_d;
ps.last_nl = true; /* remember that we just had a newline */ ps.last_nl = true; /* remember that we just had a newline */
code = (had_eof ? 0 : newline); code = (had_eof ? 0 : newline);
/* /*
* if data has been exausted, the newline is a dummy, and we should * if data has been exausted, the newline is a dummy, and we should
* return code to stop * return code to stop
*/ */
break; break;
case '\'': /* start of quoted character */ case '\'': /* start of quoted character */
case '"': /* start of string */ case '"': /* start of string */
qchar = *token; qchar = *token;
if (troff) { if (troff) {
e_token[-1] = '`'; e_token[-1] = '`';
if (qchar == '"') if (qchar == '"')
*e_token++ = '`'; *e_token++ = '`';
e_token = chfont(&bodyf, &stringf, 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, do { /* copy the string */
* since CHECK_SIZE guarantees that there while (1) { /* move one character or [/<char>]<char> */
* are at least 5 entries left */ if (*buf_ptr == '\n') {
*e_token = *buf_ptr++; printf("%d: Unterminated literal\n", line_no);
if (buf_ptr >= buf_end) goto stop_lit;
fill_buffer(); }
if (*e_token == BACKSLASH) { /* if escape, copy extra char */ CHECK_SIZE_TOKEN; /* Only have to do this once in this
if (*buf_ptr == '\n') /* check for escaped newline */ * loop, since CHECK_SIZE guarantees
++line_no; * that there are at least 5 entries
if (troff) { * left */
*++e_token = BACKSLASH; *e_token = *buf_ptr++;
if (*buf_ptr == BACKSLASH) if (buf_ptr >= buf_end)
*++e_token = BACKSLASH; fill_buffer();
} if (*e_token == BACKSLASH) { /* if escape, copy extra char */
*++e_token = *buf_ptr++; if (*buf_ptr == '\n') /* check for escaped newline */
++e_token; /* we must increment this again because we ++line_no;
* copied two chars */ if (troff) {
if (buf_ptr >= buf_end) *++e_token = BACKSLASH;
fill_buffer(); 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++ = '\'';
} }
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: stop_lit:
code = ident; code = ident;
break; break;
case ('('): case ('('):
case ('['): case ('['):
unary_delim = true; unary_delim = true;
code = lparen; code = lparen;
break; break;
case (')'): case (')'):
case (']'): case (']'):
code = rparen; code = rparen;
break; break;
case '#': case '#':
unary_delim = ps.last_u_d; unary_delim = ps.last_u_d;
code = preesc; code = preesc;
break; break;
case '?': case '?':
unary_delim = true; unary_delim = true;
code = question; code = question;
break; break;
case (':'): case (':'):
code = colon; code = colon;
unary_delim = true; unary_delim = true;
break; break;
case (';'): case (';'):
unary_delim = true; unary_delim = true;
code = semicolon; code = semicolon;
break; break;
case ('{'): case ('{'):
unary_delim = true; unary_delim = true;
/* /*
* if (ps.in_or_st) ps.block_init = 1; * if (ps.in_or_st) ps.block_init = 1;
*/ */
/* ? code = ps.block_init ? lparen : lbrace; */ /* ? code = ps.block_init ? lparen : lbrace; */
code = lbrace; code = lbrace;
break; break;
case ('}'): case ('}'):
unary_delim = true; unary_delim = true;
/* ? code = ps.block_init ? rparen : rbrace; */ /* ? code = ps.block_init ? rparen : rbrace; */
code = rbrace; code = rbrace;
break; break;
case 014: /* a form feed */ case 014: /* a form feed */
unary_delim = ps.last_u_d; unary_delim = ps.last_u_d;
ps.last_nl = true; /* remember this so we can set 'ps.col_1' ps.last_nl = true; /* remember this so we can set 'ps.col_1'
* right */ * right */
code = form_feed; code = form_feed;
break; break;
case (','): case (','):
unary_delim = true; unary_delim = true;
code = comma; code = comma;
break; break;
case '.': case '.':
unary_delim = false; unary_delim = false;
code = period; code = period;
break; break;
case '-': case '-':
case '+': /* check for -, +, --, ++ */ case '+': /* check for -, +, --, ++ */
code = (ps.last_u_d ? unary_op : binary_op); code = (ps.last_u_d ? unary_op : binary_op);
unary_delim = true; unary_delim = true;
if (*buf_ptr == token[0]) { if (*buf_ptr == token[0]) {
/* check for doubled character */ /* check for doubled character */
*e_token++ = *buf_ptr++; *e_token++ = *buf_ptr++;
/* buffer overflow will be checked at end of loop */ /* buffer overflow will be checked at end of loop */
if (last_code == ident || last_code == rparen) { if (last_code == ident || last_code == rparen) {
code = (ps.last_u_d ? unary_op : postop); code = (ps.last_u_d ? unary_op : postop);
/* check for following ++ or -- */ /* check for following ++ or -- */
unary_delim = false; 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
else if (*buf_ptr == '=') * switch */
/* 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 '=': case '=':
if (ps.in_or_st) if (ps.in_or_st)
ps.block_init = 1; ps.block_init = 1;
#ifdef undef #ifdef undef
if (chartype[*buf_ptr] == opchar) { /* we have two char assignment */ if (chartype[*buf_ptr] == opchar) { /* we have two char
e_token[-1] = *buf_ptr++; * assignment */
if ((e_token[-1] == '<' || e_token[-1] == '>') && e_token[-1] == *buf_ptr) e_token[-1] = *buf_ptr++;
*e_token++ = *buf_ptr++; if ((e_token[-1] == '<' || e_token[-1] == '>') && e_token[-1] == *buf_ptr)
*e_token++ = '='; /* Flip =+ to += */ *e_token++ = *buf_ptr++;
*e_token = 0; *e_token++ = '='; /* Flip =+ to += */
} *e_token = 0;
}
#else #else
if (*buf_ptr == '=') {/* == */ if (*buf_ptr == '=') { /* == */
*e_token++ = '='; /* Flip =+ to += */ *e_token++ = '='; /* Flip =+ to += */
buf_ptr++; buf_ptr++;
*e_token = 0; *e_token = 0;
} }
#endif #endif
code = binary_op; code = binary_op;
unary_delim = true; unary_delim = true;
break; break;
/* can drop thru!!! */ /* can drop thru!!! */
case '>': case '>':
case '<': case '<':
case '!': /* ops like <, <<, <=, !=, etc */ case '!': /* ops like <, <<, <=, !=, etc */
if (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=') { if (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=') {
*e_token++ = *buf_ptr; *e_token++ = *buf_ptr;
if (++buf_ptr >= buf_end) if (++buf_ptr >= buf_end)
fill_buffer(); fill_buffer();
} }
if (*buf_ptr == '=') if (*buf_ptr == '=')
*e_token++ = *buf_ptr++; *e_token++ = *buf_ptr++;
code = (ps.last_u_d ? unary_op : binary_op); code = (ps.last_u_d ? unary_op : binary_op);
unary_delim = true; unary_delim = true;
break; break;
default: default:
if (token[0] == '/' && *buf_ptr == '*') { if (token[0] == '/' && *buf_ptr == '*') {
/* it is start of comment */ /* it is start of comment */
*e_token++ = '*'; *e_token++ = '*';
if (++buf_ptr >= buf_end) if (++buf_ptr >= buf_end)
fill_buffer(); fill_buffer();
code = comment; code = comment;
unary_delim = ps.last_u_d; unary_delim = ps.last_u_d;
break; break;
} }
while (*(e_token - 1) == *buf_ptr || *buf_ptr == '=') { while (*(e_token - 1) == *buf_ptr || *buf_ptr == '=') {
/* /*
* handle ||, &&, etc, and also things as in int *****i * handle ||, &&, etc, and also things as in int *****i
*/ */
*e_token++ = *buf_ptr; *e_token++ = *buf_ptr;
if (++buf_ptr >= buf_end) if (++buf_ptr >= buf_end)
fill_buffer(); fill_buffer();
} }
code = (ps.last_u_d ? unary_op : binary_op); code = (ps.last_u_d ? unary_op : binary_op);
unary_delim = true; unary_delim = true;
} /* end of switch */ } /* end of switch */
if (code != newline) { if (code != newline) {
l_struct = false; l_struct = false;
last_code = code; last_code = code;
} }
if (buf_ptr >= buf_end) /* check for input buffer empty */ if (buf_ptr >= buf_end) /* check for input buffer empty */
fill_buffer(); fill_buffer();
ps.last_u_d = unary_delim; ps.last_u_d = unary_delim;
*e_token = '\0'; /* null terminate the token */ *e_token = '\0'; /* null terminate the token */
return (code); return (code);
} }
@ -568,36 +562,35 @@ stop_lit:
void void
addkey(char *key, int val) addkey(char *key, int val)
{ {
struct templ *p; struct templ *p;
int i; int i;
for (i = 0; i < nspecials; i++) { for (i = 0; i < nspecials; i++) {
p = &specials[i]; p = &specials[i];
if (p->rwd[0] == key[0] && strcmp(p->rwd, key) == 0) if (p->rwd[0] == key[0] && strcmp(p->rwd, key) == 0)
return; return;
} }
if (specials == specialsinit) { if (specials == specialsinit) {
/* /*
* Whoa. Must reallocate special table. * Whoa. Must reallocate special table.
*/ */
nspecials = sizeof (specialsinit) / sizeof (specialsinit[0]); nspecials = sizeof(specialsinit) / sizeof(specialsinit[0]);
maxspecials = nspecials + (nspecials >> 2); maxspecials = nspecials + (nspecials >> 2);
specials = calloc(maxspecials, sizeof specials[0]); specials = calloc(maxspecials, sizeof specials[0]);
if (specials == NULL) if (specials == NULL)
err(1, NULL); err(1, NULL);
memcpy(specials, specialsinit, sizeof specialsinit); memcpy(specials, specialsinit, sizeof specialsinit);
} else if (nspecials >= maxspecials) { } else if (nspecials >= maxspecials) {
int newspecials = maxspecials + (maxspecials >> 2); int newspecials = maxspecials + (maxspecials >> 2);
struct templ *specials2; struct templ *specials2;
specials2 = reallocarray(specials, newspecials, sizeof(specials[0])); specials2 = reallocarray(specials, newspecials, sizeof(specials[0]));
if (specials2 == NULL) if (specials2 == NULL)
err(1, NULL); err(1, NULL);
specials = specials2; specials = specials2;
maxspecials = newspecials; maxspecials = newspecials;
} }
p = &specials[nspecials]; p = &specials[nspecials];
p->rwd = key; p->rwd = key;
p->rwcode = val; p->rwcode = val;

389
parse.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: parse.c,v 1.9 2009/10/27 23:59:39 deraadt Exp $ */ /* $OpenBSD: parse.c,v 1.9 2009/10/27 23:59:39 deraadt Exp $ */
/* /*
* Copyright (c) 1980, 1993 * Copyright (c) 1980, 1993
@ -36,164 +36,162 @@
#include "indent_globs.h" #include "indent_globs.h"
#include "indent_codes.h" #include "indent_codes.h"
void reduce(void); void reduce(void);
void void
parse(int tk) /* the code for the construct scanned */ parse(int tk)
{ { /* the code for the construct scanned */
int i; int i;
#ifdef debug #ifdef debug
printf("%2d - %s\n", tk, token); printf("%2d - %s\n", tk, token);
#endif #endif
while (ps.p_stack[ps.tos] == ifhead && tk != elselit) { while (ps.p_stack[ps.tos] == ifhead && tk != elselit) {
/* true if we have an if without an else */ /* true if we have an if without an else */
ps.p_stack[ps.tos] = stmt; /* apply the if(..) stmt ::= stmt ps.p_stack[ps.tos] = stmt; /* apply the if(..) stmt ::= stmt
* reduction */ * reduction */
reduce(); /* see if this allows any reduction */ reduce(); /* see if this allows any reduction */
} }
switch (tk) { /* go on and figure out what to do with the switch (tk) { /* go on and figure out what to do with the
* input */ * input */
case decl: /* scanned a declaration word */ 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; 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;
break; 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 elselit: /* scanned an else */ 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;
if (ps.p_stack[ps.tos] != ifhead) case lbrace: /* scanned { */
diag(1, "Unmatched 'else'"); break_comma = false; /* don't break comma in an initial list */
else { if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl
ps.ind_level = ps.il[ps.tos]; /* indentation for else should || ps.p_stack[ps.tos] == stmtl)
* be same as for if */ ++ps.i_l_follow; /* it is a random, isolated stmt group or a
ps.i_l_follow = ps.ind_level + 1; /* everything following should * declaration */
* be in 1 level */ else {
ps.p_stack[ps.tos] = elsehead; if (s_code == e_code) {
/* remember if with else */ /*
ps.search_brace = btype_2 | ps.else_if; * only do this if there is nothing on the line
} */
break; --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
*/
}
}
case rbrace: /* scanned a } */ ps.p_stack[++ps.tos] = lbrace;
/* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */ ps.il[ps.tos] = ps.ind_level;
if (ps.p_stack[ps.tos - 1] == lbrace) { ps.p_stack[++ps.tos] = stmt;
ps.ind_level = ps.i_l_follow = ps.il[--ps.tos]; /* allow null stmt between braces */
ps.p_stack[ps.tos] = stmt; ps.il[ps.tos] = ps.i_l_follow;
} break;
else
diag(1, "Stmt nesting error.");
break;
case swstmt: /* had switch (...) */ case whilestmt: /* scanned while (...) */
ps.p_stack[++ps.tos] = swstmt; if (ps.p_stack[ps.tos] == dohead) {
ps.cstk[ps.tos] = case_ind; /* it is matched with do stmt */
/* save current case indent level */ ps.ind_level = ps.i_l_follow = ps.il[ps.tos];
ps.il[ps.tos] = ps.i_l_follow; ps.p_stack[++ps.tos] = whilestmt;
case_ind = ps.i_l_follow + ps.case_indent; /* cases should be one ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
* level down from } else { /* it is a while loop */
* switch */ ps.p_stack[++ps.tos] = whilestmt;
ps.i_l_follow += ps.case_indent + 1; /* statements should be two ps.il[ps.tos] = ps.i_l_follow;
* levels in */ ++ps.i_l_follow;
ps.search_brace = btype_2; ps.search_brace = btype_2;
break; }
case semicolon: /* this indicates a simple stmt */ break;
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 */ case elselit: /* scanned an else */
diag(1, "Unknown code to parser");
return; 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 */ } /* end of switch */
reduce(); /* see if any reduction can be done */ reduce(); /* see if any reduction can be done */
#ifdef debug #ifdef debug
for (i = 1; i <= ps.tos; ++i) for (i = 1; i <= ps.tos; ++i)
printf("(%d %d)", ps.p_stack[i], ps.il[i]); printf("(%d %d)", ps.p_stack[i], ps.il[i]);
printf("\n"); printf("\n");
#endif #endif
@ -243,80 +241,79 @@ void
reduce(void) reduce(void)
{ {
int i; int i;
for (;;) { /* keep looping until there is nothing left to for (;;) { /* keep looping until there is nothing left
* reduce */ * to reduce */
switch (ps.p_stack[ps.tos]) { switch (ps.p_stack[ps.tos]) {
case stmt:
switch (ps.p_stack[ps.tos - 1]) {
case stmt: case stmt:
case stmtl: switch (ps.p_stack[ps.tos - 1]) {
/* stmtl stmt or stmt stmt */
ps.p_stack[--ps.tos] = stmtl;
break;
case dolit: /* <do> <stmt> */ case stmt:
ps.p_stack[--ps.tos] = dohead; case stmtl:
ps.i_l_follow = ps.il[ps.tos]; /* stmtl stmt or stmt stmt */
break; ps.p_stack[--ps.tos] = stmtl;
break;
case ifstmt: case dolit: /* <do> <stmt> */
/* <if> <stmt> */ ps.p_stack[--ps.tos] = dohead;
ps.p_stack[--ps.tos] = ifhead; ps.i_l_follow = ps.il[ps.tos];
for (i = ps.tos - 1; break;
(
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: case ifstmt:
/* <switch> <stmt> */ /* <if> <stmt> */
case_ind = ps.cstk[ps.tos - 1]; 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 decl: /* finish of a declaration */ case swstmt:
case elsehead: /* <switch> <stmt> */
/* <<if> <stmt> else> <stmt> */ case_ind = ps.cstk[ps.tos - 1];
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> */ case decl: /* finish of a declaration */
return; 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;
} /* end of section for <stmt> on top of stack */ default: /* <anything else> <stmt> */
break; 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;
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,4 +1,4 @@
/* $OpenBSD: pr_comment.c,v 1.7 2009/10/27 23:59:39 deraadt Exp $ */ /* $OpenBSD: pr_comment.c,v 1.7 2009/10/27 23:59:39 deraadt Exp $ */
/* /*
* Copyright (c) 1980, 1993 * Copyright (c) 1980, 1993
@ -71,345 +71,340 @@
void void
pr_comment(void) pr_comment(void)
{ {
int now_col; /* column we are in now */ int now_col; /* column we are in now */
int adj_max_col; /* Adjusted max_col for when we decide to int adj_max_col;/* Adjusted max_col for when we decide to
* spill comments over the right margin */ * spill comments over the right margin */
char *last_bl; /* points to the last blank in the output char *last_bl; /* points to the last blank in the output
* buffer */ * buffer */
char *t_ptr; /* used for moving string */ char *t_ptr; /* used for moving string */
int unix_comment; /* tri-state variable used to decide if it is int unix_comment; /* tri-state variable used to decide
* a unix-style comment. 0 means only blanks * if it is a unix-style comment. 0
* since / *, 1 means regular style comment, 2 * means only blanks since / *, 1
* means unix style comment */ * means regular style comment, 2
int break_delim = comment_delimiter_on_blankline; * means unix style comment */
int l_just_saw_decl = ps.just_saw_decl; 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 * int ps.last_nl = 0; true iff the last significant thing
* we've seen is a newline * we've seen is a newline
*/ */
int one_liner = 1; /* true iff this comment is a one-liner */ int one_liner = 1; /* true iff this comment is a
* one-liner */
adj_max_col = max_col; adj_max_col = max_col;
ps.just_saw_decl = 0; ps.just_saw_decl = 0;
last_bl = 0; /* no blanks found so far */ last_bl = 0; /* no blanks found so far */
ps.box_com = false; /* at first, assume that we are not in ps.box_com = false; /* at first, assume that we are not in a
* a boxed comment or some other * boxed comment or some other comment that
* comment that should not be touched */ * should not be touched */
++ps.out_coms; /* keep track of number of comments */ ++ps.out_coms; /* keep track of number of comments */
unix_comment = 1; /* set flag to let us figure out if there is a unix_comment = 1; /* set flag to let us figure out if there is
* unix-style comment ** DISABLED: use 0 to * a unix-style comment ** DISABLED: use 0 to
* reenable this hack! */ * reenable this hack! */
/* Figure where to align and how to treat the comment */ /* Figure where to align and how to treat the comment */
if (ps.col_1 && !format_col1_comments) { /* if comment starts in column if (ps.col_1 && !format_col1_comments) { /* if comment starts in
* 1 it should not be touched */ * column 1 it should not be
ps.box_com = true; * touched */
ps.com_col = 1; ps.box_com = true;
} ps.com_col = 1;
else { } else {
if (*buf_ptr == '-' || *buf_ptr == '*' || *buf_ptr == '\n') { if (*buf_ptr == '-' || *buf_ptr == '*' || *buf_ptr == '\n') {
ps.box_com = true; /* a comment with a '-', '*' or newline ps.box_com = true; /* a comment with a '-', '*' or newline
* immediately after the / * is assumed to be * immediately after the / * is assumed to be
* a boxed comment */ * a boxed comment */
break_delim = 0; break_delim = 0;
} }
if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) { if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) {
/* klg: check only if this line is blank */ /* klg: check only if this line is blank */
/* /*
* If this (*and previous lines are*) blank, don't put comment way * If this (*and previous lines are*) blank, don't put comment way
* out at left * out at left
*/ */
ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1; ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
adj_max_col = block_comment_max_col; adj_max_col = block_comment_max_col;
if (ps.com_col <= 1) if (ps.com_col <= 1)
ps.com_col = 1 + !format_col1_comments; ps.com_col = 1 + !format_col1_comments;
} } else {
else { int target_col;
int target_col; break_delim = 0;
break_delim = 0; if (s_code != e_code)
if (s_code != e_code) target_col = count_spaces(compute_code_target(), s_code);
target_col = count_spaces(compute_code_target(), s_code); else {
else { target_col = 1;
target_col = 1; if (s_lab != e_lab)
if (s_lab != e_lab) target_col = count_spaces(compute_label_target(), s_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;
} }
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) { if (ps.box_com) {
buf_ptr[-2] = 0; buf_ptr[-2] = 0;
ps.n_comment_delta = 1 - count_spaces(1, in_buffer); ps.n_comment_delta = 1 - count_spaces(1, in_buffer);
buf_ptr[-2] = '/'; buf_ptr[-2] = '/';
} } else {
else { ps.n_comment_delta = 0;
ps.n_comment_delta = 0; while (*buf_ptr == ' ' || *buf_ptr == '\t')
while (*buf_ptr == ' ' || *buf_ptr == '\t') buf_ptr++;
buf_ptr++;
} }
ps.comment_delta = 0; ps.comment_delta = 0;
*e_com++ = '/'; /* put '/ *' into buffer */ *e_com++ = '/'; /* put '/ *' into buffer */
*e_com++ = '*'; *e_com++ = '*';
if (*buf_ptr != ' ' && !ps.box_com) if (*buf_ptr != ' ' && !ps.box_com)
*e_com++ = ' '; *e_com++ = ' ';
*e_com = '\0'; *e_com = '\0';
if (troff) { if (troff) {
now_col = 1; now_col = 1;
adj_max_col = 80; adj_max_col = 80;
} } else
else now_col = count_spaces(ps.com_col, s_com); /* figure what column we
now_col = count_spaces(ps.com_col, s_com); /* figure what column we * would be in if we
* would be in if we * printed the comment
* printed the comment * now */
* now */
/* Start to copy the comment */ /* Start to copy the comment */
while (1) { /* this loop will go until the comment is while (1) { /* this loop will go until the comment is
* copied */ * copied */
if (*buf_ptr > 040 && *buf_ptr != '*') if (*buf_ptr > 040 && *buf_ptr != '*')
ps.last_nl = 0; ps.last_nl = 0;
CHECK_SIZE_COM; CHECK_SIZE_COM;
switch (*buf_ptr) { /* this checks for various spcl cases */ switch (*buf_ptr) { /* this checks for various spcl cases */
case 014: /* check for a form feed */ case 014: /* check for a form feed */
if (!ps.box_com) { /* in a text comment, break the line here */ if (!ps.box_com) { /* in a text comment, break the line here */
ps.use_ff = true; ps.use_ff = true;
/* fix so dump_line uses a form feed */ /* fix so dump_line uses a form feed */
dump_line(); dump_line();
last_bl = 0; last_bl = 0;
*e_com++ = ' '; *e_com++ = ' ';
*e_com++ = '*'; *e_com++ = '*';
*e_com++ = ' '; *e_com++ = ' ';
while (*++buf_ptr == ' ' || *buf_ptr == '\t'); while (*++buf_ptr == ' ' || *buf_ptr == '\t');
} } else {
else { if (++buf_ptr >= buf_end)
if (++buf_ptr >= buf_end) fill_buffer();
fill_buffer(); *e_com++ = 014;
*e_com++ = 014; }
} break;
break;
case '\n': case '\n':
if (had_eof) { /* check for unexpected eof */ if (had_eof) { /* check for unexpected eof */
printf("Unterminated comment\n"); printf("Unterminated comment\n");
*e_com = '\0'; *e_com = '\0';
dump_line(); dump_line();
return; return;
} }
one_liner = 0; one_liner = 0;
if (ps.box_com || ps.last_nl) { /* if this is a boxed comment, if (ps.box_com || ps.last_nl) { /* if this is a boxed
* we don't ignore the newline * comment, we don't 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
*/ */
if (s_com == e_com) { ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
*e_com++ = ' '; if (ps.com_col <= 1)
*e_com++ = ' '; ps.com_col = 2;
} }
*e_com = '\0'; unix_comment = 2; /* permanently remember that we are
if (!ps.box_com && e_com - s_com > 3) { * in this type of comment */
if (break_delim == 1 && s_com[0] == '/' dump_line();
&& s_com[1] == '*' && s_com[2] == ' ') { ++line_no;
char *t = e_com; now_col = ps.com_col;
break_delim = 2; *e_com++ = ' ';
e_com = s_com + 2; /*
*e_com = 0; * fix so that the star at the start of the line will line
if (blanklines_before_blockcomments) * up
prefix_blankline_requested = 1; */
dump_line(); do /* flush leading white space */
e_com = t; if (++buf_ptr >= buf_end)
s_com[0] = s_com[1] = s_com[2] = ' '; 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;
}
} }
dump_line(); ++line_no; /* keep track of input line number */
CHECK_SIZE_COM; if (!ps.box_com) {
*e_com++ = ' '; int nstar = 1;
*e_com++ = ' '; do { /* flush any blanks and/or tabs at start of
} * next line */
dump_line(); if (++buf_ptr >= buf_end)
now_col = ps.com_col; fill_buffer();
} if (*buf_ptr == '*' && --nstar >= 0) {
else { if (++buf_ptr >= buf_end)
ps.last_nl = 1; fill_buffer();
if (unix_comment != 1) { /* we not are in unix_style if (*buf_ptr == '/')
* comment */ goto end_of_comment;
if (unix_comment == 0 && s_code == e_code) { }
/* } while (*buf_ptr == ' ' || *buf_ptr == '\t');
* if it is a UNIX-style comment, ignore the } else if (++buf_ptr >= buf_end)
* 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(); fill_buffer();
while (*buf_ptr == ' ' || *buf_ptr == '\t'); 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 && 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 && 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; 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 && 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 && 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;
}
} }
} }