aboutsummaryrefslogtreecommitdiffstats
path: root/awkgram.y
diff options
context:
space:
mode:
Diffstat (limited to 'awkgram.y')
-rw-r--r--awkgram.y867
1 files changed, 539 insertions, 328 deletions
diff --git a/awkgram.y b/awkgram.y
index 13b2bb92..e0af4c1a 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -53,11 +53,28 @@ static int isnoeffect(OPCODE type);
static INSTRUCTION *make_assignable(INSTRUCTION *ip);
static void dumpintlstr(const char *str, size_t len);
static void dumpintlstr2(const char *str1, size_t len1, const char *str2, size_t len2);
-static int include_source(INSTRUCTION *file);
-static int load_library(INSTRUCTION *file);
+static bool include_source(INSTRUCTION *file, void **srcfile_p);
+static bool load_library(INSTRUCTION *file, void **srcfile_p);
static void next_sourcefile(void);
static char *tokexpand(void);
static NODE *set_profile_text(NODE *n, const char *str, size_t len);
+static INSTRUCTION *trailing_comment;
+static INSTRUCTION *outer_comment;
+static INSTRUCTION *interblock_comment;
+static INSTRUCTION *pending_comment;
+
+#ifdef DEBUG_COMMENTS
+static void
+debug_print_comment_s(const char *name, INSTRUCTION *comment, int line)
+{
+ if (comment != NULL)
+ fprintf(stderr, "%d: %s: <%.*s>\n", line, name,
+ (int) (comment->memory->stlen - 1),
+ comment->memory->stptr);
+}
+#define debug_print_comment(comment) \
+ debug_print_comment_s(# comment, comment, __LINE__)
+#endif
#define instruction(t) bcalloc(t, 1, 0)
@@ -84,8 +101,8 @@ static void check_funcs(void);
static ssize_t read_one_line(int fd, void *buffer, size_t count);
static int one_line_close(int fd);
-static void split_comment(void);
-static void check_comment(void);
+static void merge_comments(INSTRUCTION *c1, INSTRUCTION *c2);
+static INSTRUCTION *make_braced_statements(INSTRUCTION *lbrace, INSTRUCTION *stmts, INSTRUCTION *rbrace);
static void add_sign_to_num(NODE *n, char sign);
static bool at_seen = false;
@@ -152,21 +169,10 @@ static INSTRUCTION *ip_endfile;
static INSTRUCTION *ip_beginfile;
INSTRUCTION *main_beginfile;
-static INSTRUCTION *comment = NULL;
-static INSTRUCTION *prior_comment = NULL;
-static INSTRUCTION *comment_to_save = NULL;
-static INSTRUCTION *program_comment = NULL;
-static INSTRUCTION *function_comment = NULL;
-static INSTRUCTION *block_comment = NULL;
-
-static bool func_first = true;
-static bool first_rule = true;
-
static inline INSTRUCTION *list_create(INSTRUCTION *x);
static inline INSTRUCTION *list_append(INSTRUCTION *l, INSTRUCTION *x);
static inline INSTRUCTION *list_prepend(INSTRUCTION *l, INSTRUCTION *x);
static inline INSTRUCTION *list_merge(INSTRUCTION *l1, INSTRUCTION *l2);
-static inline INSTRUCTION *add_pending_comment(INSTRUCTION *stmt);
extern double fmod(double x, double y);
@@ -214,12 +220,22 @@ extern double fmod(double x, double y);
program
: /* empty */
+ { $$ = NULL; }
| program rule
{
rule = 0;
yyerrok;
}
| program nls
+ {
+ if ($2 != NULL) {
+ if ($1 == NULL)
+ outer_comment = $2;
+ else
+ interblock_comment = $2;
+ }
+ $$ = $1;
+ }
| program LEX_EOF
{
next_sourcefile();
@@ -239,7 +255,10 @@ rule
: pattern action
{
(void) append_rule($1, $2);
- first_rule = false;
+ if (pending_comment != NULL) {
+ interblock_comment = pending_comment;
+ pending_comment = NULL;
+ }
}
| pattern statement_term
{
@@ -249,26 +268,41 @@ rule
} else if ($1 == NULL) {
msg(_("each rule must have a pattern or an action part"));
errcount++;
- } else /* pattern rule with non-empty pattern */
+ } else { /* pattern rule with non-empty pattern */
+ if ($2 != NULL)
+ list_append($1, $2);
(void) append_rule($1, NULL);
+ }
}
| function_prologue action
{
in_function = NULL;
(void) mk_function($1, $2);
want_param_names = DONT_CHECK;
+ if (pending_comment != NULL) {
+ interblock_comment = pending_comment;
+ pending_comment = NULL;
+ }
yyerrok;
}
| '@' LEX_INCLUDE source statement_term
{
want_source = false;
at_seen = false;
+ if ($3 != NULL && $4 != NULL) {
+ SRCFILE *s = (SRCFILE *) $3;
+ s->comment = $4;
+ }
yyerrok;
}
| '@' LEX_LOAD library statement_term
{
want_source = false;
at_seen = false;
+ if ($3 != NULL && $4 != NULL) {
+ SRCFILE *s = (SRCFILE *) $3;
+ s->comment = $4;
+ }
yyerrok;
}
;
@@ -276,11 +310,13 @@ rule
source
: FILENAME
{
- if (include_source($1) < 0)
+ void *srcfile = NULL;
+
+ if (! include_source($1, & srcfile))
YYABORT;
efree($1->lextok);
bcfree($1);
- $$ = NULL;
+ $$ = (INSTRUCTION *) srcfile;
}
| FILENAME error
{ $$ = NULL; }
@@ -291,11 +327,13 @@ source
library
: FILENAME
{
- if (load_library($1) < 0)
+ void *srcfile;
+
+ if (! load_library($1, & srcfile))
YYABORT;
efree($1->lextok);
bcfree($1);
- $$ = NULL;
+ $$ = (INSTRUCTION *) srcfile;
}
| FILENAME error
{ $$ = NULL; }
@@ -307,94 +345,77 @@ pattern
: /* empty */
{
rule = Rule;
- if (comment != NULL) {
- $$ = list_create(comment);
- comment = NULL;
- } else
- $$ = NULL;
+ $$ = NULL;
}
| exp
{
rule = Rule;
- if (comment != NULL) {
- $$ = list_prepend($1, comment);
- comment = NULL;
- } else
- $$ = $1;
}
- | exp ',' opt_nls exp
+ | exp comma exp
{
INSTRUCTION *tp;
add_lint($1, LINT_assign_in_cond);
- add_lint($4, LINT_assign_in_cond);
+ add_lint($3, LINT_assign_in_cond);
tp = instruction(Op_no_op);
list_prepend($1, bcalloc(Op_line_range, !!do_pretty_print + 1, 0));
$1->nexti->triggered = false;
- $1->nexti->target_jmp = $4->nexti;
+ $1->nexti->target_jmp = $3->nexti;
list_append($1, instruction(Op_cond_pair));
$1->lasti->line_range = $1->nexti;
$1->lasti->target_jmp = tp;
- list_append($4, instruction(Op_cond_pair));
- $4->lasti->line_range = $1->nexti;
- $4->lasti->target_jmp = tp;
+ list_append($3, instruction(Op_cond_pair));
+ $3->lasti->line_range = $1->nexti;
+ $3->lasti->target_jmp = tp;
if (do_pretty_print) {
($1->nexti + 1)->condpair_left = $1->lasti;
- ($1->nexti + 1)->condpair_right = $4->lasti;
+ ($1->nexti + 1)->condpair_right = $3->lasti;
}
- if (comment != NULL) {
- $$ = list_append(list_merge(list_prepend($1, comment), $4), tp);
- comment = NULL;
- } else
- $$ = list_append(list_merge($1, $4), tp);
+ /* Put any comments in front of the range expression */
+ if ($2 != NULL)
+ $$ = list_append(list_merge(list_prepend($1, $2), $3), tp);
+ else
+ $$ = list_append(list_merge($1, $3), tp);
rule = Rule;
}
| LEX_BEGIN
{
static int begin_seen = 0;
- func_first = false;
if (do_lint_old && ++begin_seen == 2)
warning_ln($1->source_line,
_("old awk does not support multiple `BEGIN' or `END' rules"));
$1->in_rule = rule = BEGIN;
$1->source_file = source;
- check_comment();
$$ = $1;
}
| LEX_END
{
static int end_seen = 0;
- func_first = false;
if (do_lint_old && ++end_seen == 2)
warning_ln($1->source_line,
_("old awk does not support multiple `BEGIN' or `END' rules"));
$1->in_rule = rule = END;
$1->source_file = source;
- check_comment();
$$ = $1;
}
| LEX_BEGINFILE
{
- func_first = false;
$1->in_rule = rule = BEGINFILE;
$1->source_file = source;
- check_comment();
$$ = $1;
}
| LEX_ENDFILE
{
- func_first = false;
$1->in_rule = rule = ENDFILE;
$1->source_file = source;
- check_comment();
$$ = $1;
}
;
@@ -402,11 +423,17 @@ pattern
action
: l_brace statements r_brace opt_semi opt_nls
{
- INSTRUCTION *ip;
- if ($2 == NULL)
- ip = list_create(instruction(Op_no_op));
- else
- ip = $2;
+ INSTRUCTION *ip = make_braced_statements($1, $2, $3);
+
+ if ($3 != NULL && $5 != NULL) {
+ merge_comments($3, $5);
+ pending_comment = $3;
+ } else if ($3 != NULL) {
+ pending_comment = $3;
+ } else if ($5 != NULL) {
+ pending_comment = $5;
+ }
+
$$ = ip;
}
;
@@ -437,33 +464,21 @@ lex_builtin
function_prologue
: LEX_FUNCTION func_name '(' { want_param_names = FUNC_HEADER; } opt_param_list r_paren opt_nls
{
- /*
- * treat any comments between BOF and the first function
- * definition (with no intervening BEGIN etc block) as
- * program comments. Special kludge: iff there are more
- * than one such comments, treat the last as a function
- * comment.
- */
- if (prior_comment != NULL) {
- comment_to_save = prior_comment;
- prior_comment = NULL;
- } else if (comment != NULL) {
- comment_to_save = comment;
- comment = NULL;
- } else
- comment_to_save = NULL;
-
- if (comment_to_save != NULL && func_first
- && strstr(comment_to_save->memory->stptr, "\n\n") != NULL)
- split_comment();
-
- /* save any other pre-function comment as function comment */
- if (comment_to_save != NULL) {
- function_comment = comment_to_save;
- comment_to_save = NULL;
+ INSTRUCTION *func_comment = NULL;
+ // Merge any comments found in the parameter list with those
+ // following the function header, associate the whole shebang
+ // with the function as one block comment.
+ if ($5 != NULL && $5->comment != NULL) {
+ if ($7 != NULL) {
+ merge_comments($5->comment, $7);
+ }
+ func_comment = $5->comment;
+ } else if ($7 != NULL) {
+ func_comment = $7;
}
- func_first = false;
+
$1->source_file = source;
+ $1->comment = func_comment;
if (install_function($2->lextok, $1, $5) < 0)
YYABORT;
in_function = $2->lextok;
@@ -536,61 +551,25 @@ a_slash
statements
: /* empty */
- {
- if (prior_comment != NULL) {
- $$ = list_create(prior_comment);
- prior_comment = NULL;
- } else if (comment != NULL) {
- $$ = list_create(comment);
- comment = NULL;
- } else
- $$ = NULL;
- }
+ { $$ = NULL; }
| statements statement
{
if ($2 == NULL) {
- if (prior_comment != NULL) {
- $$ = list_append($1, prior_comment);
- prior_comment = NULL;
- if (comment != NULL) {
- $$ = list_append($$, comment);
- comment = NULL;
- }
- } else if (comment != NULL) {
- $$ = list_append($1, comment);
- comment = NULL;
- } else
- $$ = $1;
+ $$ = $1;
} else {
add_lint($2, LINT_no_effect);
if ($1 == NULL) {
- if (prior_comment != NULL) {
- $$ = list_append($2, prior_comment);
- prior_comment = NULL;
- if (comment != NULL) {
- $$ = list_append($$, comment);
- comment = NULL;
- }
- } else if (comment != NULL) {
- $$ = list_append($2, comment);
- comment = NULL;
- } else
- $$ = $2;
+ $$ = $2;
} else {
- if (prior_comment != NULL) {
- list_append($2, prior_comment);
- prior_comment = NULL;
- if (comment != NULL) {
- list_append($2, comment);
- comment = NULL;
- }
- } else if (comment != NULL) {
- list_append($2, comment);
- comment = NULL;
- }
$$ = list_merge($1, $2);
}
}
+
+ if (trailing_comment != NULL) {
+ $$ = list_append($$, trailing_comment);
+ trailing_comment = NULL;
+ }
+
yyerrok;
}
| statements error
@@ -598,15 +577,27 @@ statements
;
statement_term
- : nls
- | semi opt_nls
+ : nls { $$ = $1; }
+ | semi opt_nls { $$ = $2; }
;
statement
: semi opt_nls
- { $$ = NULL; }
+ {
+ if ($2 != NULL) {
+ INSTRUCTION *ip;
+
+ merge_comments($2, NULL);
+ ip = list_create(instruction(Op_no_op));
+ $$ = list_append(ip, $2);
+ } else
+ $$ = NULL;
+ }
| l_brace statements r_brace
- { $$ = $2; }
+ {
+ trailing_comment = $3; // NULL or comment
+ $$ = make_braced_statements($1, $2, $3);
+ }
| if_statement
{
if (do_pretty_print)
@@ -632,8 +623,9 @@ statement
if ($7 != NULL) {
curr = $7->nexti;
bcfree($7); /* Op_list */
- } /* else
- curr = NULL; */
+ }
+ /* else
+ curr = NULL; */
for (; curr != NULL; curr = nextc) {
INSTRUCTION *caseexp = curr->case_exp;
@@ -689,16 +681,33 @@ statement
ip = $3;
if (do_pretty_print) {
+ // first merge comments
+ INSTRUCTION *head_comment = NULL;
+
+ if ($5 != NULL && $6 != NULL) {
+ merge_comments($5, $6);
+ head_comment = $5;
+ } else if ($5 != NULL)
+ head_comment = $5;
+ else
+ head_comment = $6;
+
+ $1->comment = head_comment;
+
(void) list_prepend(ip, $1);
(void) list_prepend(ip, instruction(Op_exec_count));
$1->target_break = tbreak;
($1 + 1)->switch_start = cexp->nexti;
($1 + 1)->switch_end = cexp->lasti;
- }/* else
- $1 is NULL */
+ ($1 + 1)->switch_end->comment = $9;
+ }
+ /* else
+ $1 is NULL */
(void) list_append(cexp, dflt);
(void) list_merge(ip, cexp);
+ if ($8 != NULL)
+ (void) list_append(cstmt, $8);
$$ = list_merge(ip, cstmt);
break_allowed--;
@@ -733,8 +742,17 @@ statement
$1->target_continue = tcont;
($1 + 1)->while_body = ip->lasti;
(void) list_prepend(ip, $1);
- }/* else
- $1 is NULL */
+ }
+ /* else
+ $1 is NULL */
+
+ if ($5 != NULL) {
+ if ($6 == NULL)
+ $6 = list_create(instruction(Op_no_op));
+
+ $5->memory->comment_type = BLOCK_COMMENT;
+ $6 = list_prepend($6, $5);
+ }
if ($6 != NULL)
(void) list_merge(ip, $6);
@@ -769,8 +787,13 @@ statement
ip = list_merge($3, $6);
else
ip = list_prepend($6, instruction(Op_no_op));
+
+ if ($2 != NULL)
+ (void) list_prepend(ip, $2);
+
if (do_pretty_print)
(void) list_prepend(ip, instruction(Op_exec_count));
+
(void) list_append(ip, instruction(Op_jmp_true));
ip->lasti->target_jmp = ip->nexti;
$$ = list_append(ip, tbreak);
@@ -785,7 +808,10 @@ statement
($1 + 1)->doloop_cond = tcont;
$$ = list_prepend(ip, $1);
bcfree($4);
- } /* else
+ if ($8 != NULL)
+ $1->comment = $8;
+ }
+ /* else
$1 and $4 are NULLs */
}
| LEX_FOR '(' NAME LEX_IN simple_variable r_paren opt_nls statement
@@ -801,7 +827,8 @@ statement
&& strcmp($8->nexti->memory->vname, var_name) == 0
) {
- /* Efficiency hack. Recognize the special case of
+ /*
+ * Efficiency hack. Recognize the special case of
*
* for (iggy in foo)
* delete foo[iggy]
@@ -833,6 +860,10 @@ statement
bcfree($3);
bcfree($4);
bcfree($5);
+ if ($7 != NULL) {
+ merge_comments($7, NULL);
+ $8 = list_prepend($8, $7);
+ }
$$ = $8;
} else
goto regular_loop;
@@ -867,8 +898,9 @@ regular_loop:
$1->target_continue = tcont;
$1->target_break = tbreak;
(void) list_append(ip, $1);
- } /* else
- $1 is NULL */
+ }
+ /* else
+ $1 is NULL */
/* add update_FOO instruction if necessary */
if ($4->array_var->type == Node_var && $4->array_var->var_update) {
@@ -889,8 +921,15 @@ regular_loop:
($1 + 1)->forloop_body = ip->lasti;
}
- if ($8 != NULL)
+ if ($7 != NULL)
+ merge_comments($7, NULL);
+
+ if ($8 != NULL) {
+ if ($7 != NULL)
+ $8 = list_prepend($8, $7);
(void) list_merge(ip, $8);
+ } else if ($7 != NULL)
+ (void) list_append(ip, $7);
(void) list_append(ip, instruction(Op_jmp));
ip->lasti->target_jmp = $4;
@@ -903,6 +942,20 @@ regular_loop:
}
| LEX_FOR '(' opt_simple_stmt semi opt_nls exp semi opt_nls opt_simple_stmt r_paren opt_nls statement
{
+ if ($5 != NULL) {
+ merge_comments($5, NULL);
+ $1->comment = $5;
+ }
+ if ($8 != NULL) {
+ merge_comments($8, NULL);
+ if ($1->comment == NULL) {
+ $8->memory->comment_type = FOR_COMMENT;
+ $1->comment = $8;
+ } else
+ $1->comment->comment = $8;
+ }
+ if ($11 != NULL)
+ $12 = list_prepend($12, $11);
$$ = mk_for_loop($1, $3, $6, $9, $12);
break_allowed--;
@@ -910,6 +963,20 @@ regular_loop:
}
| LEX_FOR '(' opt_simple_stmt semi opt_nls semi opt_nls opt_simple_stmt r_paren opt_nls statement
{
+ if ($5 != NULL) {
+ merge_comments($5, NULL);
+ $1->comment = $5;
+ }
+ if ($7 != NULL) {
+ merge_comments($7, NULL);
+ if ($1->comment == NULL) {
+ $7->memory->comment_type = FOR_COMMENT;
+ $1->comment = $7;
+ } else
+ $1->comment->comment = $7;
+ }
+ if ($10 != NULL)
+ $11 = list_prepend($11, $10);
$$ = mk_for_loop($1, $3, (INSTRUCTION *) NULL, $8, $11);
break_allowed--;
@@ -921,7 +988,6 @@ regular_loop:
$$ = list_prepend($1, instruction(Op_exec_count));
else
$$ = $1;
- $$ = add_pending_comment($$);
}
;
@@ -933,8 +999,8 @@ non_compound_stmt
_("`break' is not allowed outside a loop or switch"));
$1->target_jmp = NULL;
$$ = list_create($1);
- $$ = add_pending_comment($$);
-
+ if ($2 != NULL)
+ $$ = list_append($$, $2);
}
| LEX_CONTINUE statement_term
{
@@ -943,8 +1009,8 @@ non_compound_stmt
_("`continue' is not allowed outside a loop"));
$1->target_jmp = NULL;
$$ = list_create($1);
- $$ = add_pending_comment($$);
-
+ if ($2 != NULL)
+ $$ = list_append($$, $2);
}
| LEX_NEXT statement_term
{
@@ -954,7 +1020,8 @@ non_compound_stmt
_("`next' used in %s action"), ruletab[rule]);
$1->target_jmp = ip_rec;
$$ = list_create($1);
- $$ = add_pending_comment($$);
+ if ($2 != NULL)
+ $$ = list_append($$, $2);
}
| LEX_NEXTFILE statement_term
{
@@ -966,7 +1033,8 @@ non_compound_stmt
$1->target_newfile = ip_newfile;
$1->target_endfile = ip_endfile;
$$ = list_create($1);
- $$ = add_pending_comment($$);
+ if ($2 != NULL)
+ $$ = list_append($$, $2);
}
| LEX_EXIT opt_exp statement_term
{
@@ -982,7 +1050,8 @@ non_compound_stmt
$$->nexti->memory = dupnode(Nnull_string);
} else
$$ = list_append($2, $1);
- $$ = add_pending_comment($$);
+ if ($3 != NULL)
+ $$ = list_append($$, $3);
}
| LEX_RETURN
{
@@ -995,10 +1064,16 @@ non_compound_stmt
$$->nexti->memory = dupnode(Nnull_string);
} else
$$ = list_append($3, $1);
-
- $$ = add_pending_comment($$);
+ if ($4 != NULL)
+ $$ = list_append($$, $4);
}
| simple_stmt statement_term
+ {
+ if ($2 != NULL)
+ $$ = list_append($1, $2);
+ else
+ $$ = $1;
+ }
;
/*
@@ -1018,7 +1093,7 @@ simple_stmt
* which is faster for these two cases.
*/
- if ($1->opcode == Op_K_print &&
+ if (do_optimize && $1->opcode == Op_K_print &&
($3 == NULL
|| ($3->lasti->opcode == Op_field_spec
&& $3->nexti->nexti->nexti == $3->lasti
@@ -1106,7 +1181,6 @@ regular_print:
}
}
}
- $$ = add_pending_comment($$);
}
| LEX_DELETE NAME { sub_counter = 0; } delete_subscript_list
@@ -1141,7 +1215,6 @@ regular_print:
$1->expr_count = sub_counter;
$$ = list_append(list_append($4, $2), $1);
}
- $$ = add_pending_comment($$);
}
| LEX_DELETE '(' NAME ')'
/*
@@ -1172,12 +1245,10 @@ regular_print:
else if ($3->memory == func_table)
fatal(_("`delete' is not allowed with FUNCTAB"));
}
- $$ = add_pending_comment($$);
}
| exp
{
$$ = optimize_assignment($1);
- $$ = add_pending_comment($$);
}
;
@@ -1212,6 +1283,7 @@ case_statement
(void) list_prepend(casestmt, instruction(Op_exec_count));
$1->case_exp = $2;
$1->case_stmt = casestmt;
+ $1->comment = $4;
bcfree($3);
$$ = $1;
}
@@ -1224,6 +1296,7 @@ case_statement
(void) list_prepend(casestmt, instruction(Op_exec_count));
bcfree($2);
$1->case_stmt = casestmt;
+ $1->comment = $3;
$$ = $1;
}
;
@@ -1305,23 +1378,51 @@ output_redir
if_statement
: LEX_IF '(' exp r_paren opt_nls statement
{
+ if ($5 != NULL)
+ $1->comment = $5;
$$ = mk_condition($3, $1, $6, NULL, NULL);
}
| LEX_IF '(' exp r_paren opt_nls statement
LEX_ELSE opt_nls statement
{
+ if ($5 != NULL)
+ $1->comment = $5;
+ if ($8 != NULL)
+ $7->comment = $8;
$$ = mk_condition($3, $1, $6, $7, $9);
}
;
nls
: NEWLINE
+ {
+ $$ = $1;
+ }
| nls NEWLINE
+ {
+ if ($1 != NULL && $2 != NULL) {
+ if ($1->memory->comment_type == EOL_COMMENT) {
+ assert($2->memory->comment_type == BLOCK_COMMENT);
+ $1->comment = $2; // chain them
+ } else {
+ merge_comments($1, $2);
+ }
+
+ $$ = $1;
+ } else if ($1 != NULL) {
+ $$ = $1;
+ } else if ($2 != NULL) {
+ $$ = $2;
+ } else
+ $$ = NULL;
+ }
;
opt_nls
: /* empty */
+ { $$ = NULL; }
| nls
+ { $$ = $1; }
;
input_redir
@@ -1350,9 +1451,17 @@ param_list
| param_list comma NAME
{
if ($1 != NULL && $3 != NULL) {
- $3->param_count = $1->lasti->param_count + 1;
+ $3->param_count = $1->lasti->param_count + 1;
$$ = list_append($1, $3);
yyerrok;
+
+ // newlines are allowed after commas, catch any comments
+ if ($2 != NULL) {
+ if ($1->comment != NULL)
+ merge_comments($1->comment, $2);
+ else
+ $1->comment = $2;
+ }
} else
$$ = NULL;
}
@@ -1384,6 +1493,8 @@ expression_list
{ $$ = mk_expression_list(NULL, $1); }
| expression_list comma exp
{
+ if ($2 != NULL)
+ $1->lasti->comment = $2;
$$ = mk_expression_list($1, $3);
yyerrok;
}
@@ -1405,6 +1516,8 @@ expression_list
| expression_list comma error
{
/* Ditto */
+ if ($2 != NULL)
+ $1->lasti->comment = $2;
$$ = $1;
}
;
@@ -1421,6 +1534,8 @@ fcall_expression_list
{ $$ = mk_expression_list(NULL, $1); }
| fcall_expression_list comma fcall_exp
{
+ if ($2 != NULL)
+ $1->lasti->comment = $2;
$$ = mk_expression_list($1, $3);
yyerrok;
}
@@ -1442,6 +1557,8 @@ fcall_expression_list
| fcall_expression_list comma error
{
/* Ditto */
+ if ($2 != NULL)
+ $1->comment = $2;
$$ = $1;
}
;
@@ -2006,15 +2123,16 @@ opt_incdec
{
$1->opcode = Op_postdecrement;
}
- | /* empty */ { $$ = NULL; }
+ | /* empty */
+ { $$ = NULL; }
;
l_brace
- : '{' opt_nls
+ : '{' opt_nls { $$ = $2; }
;
r_brace
- : '}' opt_nls { yyerrok; }
+ : '}' opt_nls { $$ = $2; yyerrok; }
;
r_paren
@@ -2023,6 +2141,7 @@ r_paren
opt_semi
: /* empty */
+ { $$ = NULL; }
| semi
;
@@ -2035,7 +2154,7 @@ colon
;
comma
- : ',' opt_nls { yyerrok; }
+ : ',' opt_nls { $$ = $2; yyerrok; }
;
%%
@@ -2115,8 +2234,8 @@ static const struct token tokentab[] = {
{"exp", Op_builtin, LEX_BUILTIN, A(1), do_exp, MPF(exp)},
{"fflush", Op_builtin, LEX_BUILTIN, A(0)|A(1), do_fflush, 0},
{"for", Op_K_for, LEX_FOR, BREAK|CONTINUE, 0, 0},
-{"func", Op_func, LEX_FUNCTION, NOT_POSIX|NOT_OLD, 0, 0},
-{"function",Op_func, LEX_FUNCTION, NOT_OLD, 0, 0},
+{"func", Op_func, LEX_FUNCTION, NOT_POSIX|NOT_OLD, 0, 0},
+{"function", Op_func, LEX_FUNCTION, NOT_OLD, 0, 0},
{"gensub", Op_sub_builtin, LEX_BUILTIN, GAWKX|A(3)|A(4), 0, 0},
{"getline", Op_K_getline_redir, LEX_GETLINE, NOT_OLD, 0, 0},
{"gsub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0, 0},
@@ -2161,7 +2280,7 @@ static const struct token tokentab[] = {
{"systime", Op_builtin, LEX_BUILTIN, GAWKX|A(0), do_systime, 0},
{"tolower", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_tolower, 0},
{"toupper", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_toupper, 0},
-{"typeof", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_typeof, 0},
+{"typeof", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_typeof, 0},
{"while", Op_K_while, LEX_WHILE, BREAK|CONTINUE, 0, 0},
{"xor", Op_builtin, LEX_BUILTIN, GAWKX, do_xor, MPF(xor)},
};
@@ -2475,11 +2594,12 @@ mk_program()
cp = end_block;
else
cp = list_merge(begin_block, end_block);
- if (program_comment != NULL) {
- (void) list_prepend(cp, program_comment);
+
+ if (interblock_comment != NULL) {
+ (void) list_append(cp, interblock_comment);
+ interblock_comment = NULL;
}
- if (comment != NULL)
- (void) list_append(cp, comment);
+
(void) list_append(cp, ip_atexit);
(void) list_append(cp, instruction(Op_stop));
@@ -2490,6 +2610,16 @@ mk_program()
(void) list_merge(cp, beginfile_block);
(void) list_merge(cp, endfile_block);
+ if (outer_comment != NULL) {
+ cp = list_merge(list_create(outer_comment), cp);
+ outer_comment = NULL;
+ }
+
+ if (interblock_comment != NULL) {
+ (void) list_append(cp, interblock_comment);
+ interblock_comment = NULL;
+ }
+
goto out;
} else {
@@ -2512,12 +2642,16 @@ mk_program()
if (begin_block != NULL)
cp = list_merge(begin_block, cp);
- if (program_comment != NULL) {
- (void) list_prepend(cp, program_comment);
+ if (outer_comment != NULL) {
+ cp = list_merge(list_create(outer_comment), cp);
+ outer_comment = NULL;
}
- if (comment != NULL) {
- (void) list_append(cp, comment);
+
+ if (interblock_comment != NULL) {
+ (void) list_append(cp, interblock_comment);
+ interblock_comment = NULL;
}
+
(void) list_append(cp, ip_atexit);
(void) list_append(cp, instruction(Op_stop));
@@ -2525,10 +2659,6 @@ out:
/* delete the Op_list, not needed */
tmp = cp->nexti;
bcfree(cp);
- /* these variables are not used again but zap them anyway. */
- comment = NULL;
- function_comment = NULL;
- program_comment = NULL;
return tmp;
#undef begin_block
@@ -2703,33 +2833,35 @@ add_srcfile(enum srctype stype, char *src, SRCFILE *thisfile, bool *already_incl
/* include_source --- read program from source included using `@include' */
-static int
-include_source(INSTRUCTION *file)
+static bool
+include_source(INSTRUCTION *file, void **srcfile_p)
{
SRCFILE *s;
char *src = file->lextok;
int errcode;
bool already_included;
+ *srcfile_p = NULL;
+
if (do_traditional || do_posix) {
error_ln(file->source_line, _("@include is a gawk extension"));
- return -1;
+ return false;
}
if (strlen(src) == 0) {
if (do_lint)
lintwarn_ln(file->source_line, _("empty filename after @include"));
- return 0;
+ return true;
}
s = add_srcfile(SRC_INC, src, sourcefile, &already_included, &errcode);
if (s == NULL) {
if (already_included)
- return 0;
+ return true;
error_ln(file->source_line,
_("can't open source file `%s' for reading (%s)"),
src, errcode ? strerror(errcode) : _("reason unknown"));
- return -1;
+ return false;
}
/* save scanner state for the current sourcefile */
@@ -2748,42 +2880,53 @@ include_source(INSTRUCTION *file)
lasttok = 0;
lexeof = false;
eof_warned = false;
- return 0;
+ *srcfile_p = (void *) s;
+ return true;
}
/* load_library --- load a shared library */
-static int
-load_library(INSTRUCTION *file)
+static bool
+load_library(INSTRUCTION *file, void **srcfile_p)
{
SRCFILE *s;
char *src = file->lextok;
int errcode;
bool already_included;
+ *srcfile_p = NULL;
+
if (do_traditional || do_posix) {
error_ln(file->source_line, _("@load is a gawk extension"));
- return -1;
+ return false;
}
+
if (strlen(src) == 0) {
if (do_lint)
lintwarn_ln(file->source_line, _("empty filename after @load"));
- return 0;
+ return true;
}
- s = add_srcfile(SRC_EXTLIB, src, sourcefile, &already_included, &errcode);
- if (s == NULL) {
- if (already_included)
- return 0;
- error_ln(file->source_line,
- _("can't open shared library `%s' for reading (%s)"),
- src, errcode ? strerror(errcode) : _("reason unknown"));
- return -1;
+ if (do_pretty_print && ! do_profile) {
+ // create a fake one, don't try to open the file
+ s = do_add_srcfile(SRC_EXTLIB, src, src, sourcefile);
+ } else {
+ s = add_srcfile(SRC_EXTLIB, src, sourcefile, &already_included, &errcode);
+ if (s == NULL) {
+ if (already_included)
+ return true;
+ error_ln(file->source_line,
+ _("can't open shared library `%s' for reading (%s)"),
+ src, errcode ? strerror(errcode) : _("reason unknown"));
+ return false;
+ }
+
+ load_ext(s->fullpath);
}
- load_ext(s->fullpath);
- return 0;
+ *srcfile_p = (void *) s;
+ return true;
}
/* next_sourcefile --- read program from the next source in srcfiles */
@@ -3191,37 +3334,23 @@ pushback(void)
(! lexeof && lexptr && lexptr > lexptr_begin ? lexptr-- : lexptr);
}
-/* check_comment --- check for block comment */
-
-void
-check_comment(void)
-{
- if (comment != NULL) {
- if (first_rule) {
- program_comment = comment;
- } else
- block_comment = comment;
- comment = NULL;
- }
- first_rule = false;
-}
-
/*
* get_comment --- collect comment text.
* Flag = EOL_COMMENT for end-of-line comments.
- * Flag = FULL_COMMENT for self-contained comments.
+ * Flag = BLOCK_COMMENT for self-contained comments.
*/
-int
-get_comment(int flag)
+static int
+get_comment(enum commenttype flag, INSTRUCTION **comment_instruction)
{
int c;
int sl;
+ char *p1;
+ char *p2;
+
tok = tokstart;
tokadd('#');
sl = sourceline;
- char *p1;
- char *p2;
while (true) {
while ((c = nextc(false)) != '\n' && c != END_FILE) {
@@ -3257,9 +3386,6 @@ get_comment(int flag)
break;
}
- if (comment != NULL)
- prior_comment = comment;
-
/* remove any trailing blank lines (consecutive \n) from comment */
p1 = tok - 1;
p2 = tok - 2;
@@ -3269,49 +3395,18 @@ get_comment(int flag)
tok--;
}
- comment = bcalloc(Op_comment, 1, sl);
- comment->source_file = source;
- comment->memory = make_str_node(tokstart, tok - tokstart, 0);
- comment->memory->comment_type = flag;
+ (*comment_instruction) = bcalloc(Op_comment, 1, sl);
+ (*comment_instruction)->source_file = source;
+ (*comment_instruction)->memory = make_str_node(tokstart, tok - tokstart, 0);
+ (*comment_instruction)->memory->comment_type = flag;
return c;
}
-/* split_comment --- split initial comment text into program and function parts */
-
-static void
-split_comment(void)
-{
- char *p;
- int l;
- NODE *n;
-
- p = comment_to_save->memory->stptr;
- l = comment_to_save->memory->stlen - 3;
- /* have at least two comments so split at last blank line (\n\n) */
- while (l >= 0) {
- if (p[l] == '\n' && p[l+1] == '\n') {
- function_comment = comment_to_save;
- n = function_comment->memory;
- function_comment->memory = make_string(p + l + 2, n->stlen - l - 2);
- /* create program comment */
- program_comment = bcalloc(Op_comment, 1, sourceline);
- program_comment->source_file = comment_to_save->source_file;
- p[l + 2] = 0;
- program_comment->memory = make_str_node(p, l + 2, 0);
- comment_to_save = NULL;
- freenode(n);
- break;
- }
- else
- l--;
- }
-}
-
/* allow_newline --- allow newline after &&, ||, ? and : */
static void
-allow_newline(void)
+allow_newline(INSTRUCTION **new_comment)
{
int c;
@@ -3323,8 +3418,8 @@ allow_newline(void)
}
if (c == '#') {
if (do_pretty_print && ! do_profile) {
- /* collect comment byte code iff doing pretty print but not profiling. */
- c = get_comment(EOL_COMMENT);
+ /* collect comment byte code iff doing pretty print but not profiling. */
+ c = get_comment(EOL_COMMENT, new_comment);
} else {
while ((c = nextc(false)) != '\n' && c != END_FILE)
continue;
@@ -3391,6 +3486,7 @@ yylex(void)
bool intlstr = false;
AWKNUM d;
bool collecting_typed_regexp = false;
+ static int qm_col_count = 0;
#define GET_INSTRUCTION(op) bcalloc(op, 1, sourceline)
@@ -3555,18 +3651,25 @@ retry:
return lasttok = NEWLINE;
case '#': /* it's a comment */
+ yylval = NULL;
if (do_pretty_print && ! do_profile) {
/*
* Collect comment byte code iff doing pretty print
* but not profiling.
*/
+ INSTRUCTION *new_comment;
+
if (lasttok == NEWLINE || lasttok == 0)
- c = get_comment(FULL_COMMENT);
+ c = get_comment(BLOCK_COMMENT, & new_comment);
else
- c = get_comment(EOL_COMMENT);
+ c = get_comment(EOL_COMMENT, & new_comment);
- if (c == END_FILE)
- return lasttok = NEWLINE_EOF;
+ yylval = new_comment;
+
+ if (c == END_FILE) {
+ pushback();
+ return lasttok = NEWLINE;
+ }
} else {
while ((c = nextc(false)) != '\n') {
if (c == END_FILE)
@@ -3595,7 +3698,10 @@ retry:
* Use it at your own risk. We think it's a bad idea, which
* is why it's not on by default.
*/
+ yylval = NULL;
if (! do_traditional) {
+ INSTRUCTION *new_comment;
+
/* strip trailing white-space and/or comment */
while ((c = nextc(true)) == ' ' || c == '\t' || c == '\r')
continue;
@@ -3607,9 +3713,11 @@ retry:
lintwarn(
_("use of `\\ #...' line continuation is not portable"));
}
- if (do_pretty_print && ! do_profile)
- c = get_comment(EOL_COMMENT);
- else {
+ if (do_pretty_print && ! do_profile) {
+ c = get_comment(EOL_COMMENT, & new_comment);
+ yylval = new_comment;
+ return lasttok = c;
+ } else {
while ((c = nextc(false)) != '\n')
if (c == END_FILE)
break;
@@ -3630,11 +3738,20 @@ retry:
}
break;
- case ':':
case '?':
+ qm_col_count++;
+ // fall through
+ case ':':
yylval = GET_INSTRUCTION(Op_cond_exp);
- if (! do_posix)
- allow_newline();
+ if (qm_col_count > 0) {
+ if (! do_posix) {
+ INSTRUCTION *new_comment = NULL;
+ allow_newline(& new_comment);
+ yylval->comment = new_comment;
+ }
+ if (c == ':')
+ qm_col_count--;
+ }
return lasttok = c;
/*
@@ -4056,7 +4173,10 @@ retry:
case '&':
if ((c = nextc(true)) == '&') {
yylval = GET_INSTRUCTION(Op_and);
- allow_newline();
+ INSTRUCTION *new_comment = NULL;
+ allow_newline(& new_comment);
+ yylval->comment = new_comment;
+
return lasttok = LEX_AND;
}
pushback();
@@ -4066,11 +4186,15 @@ retry:
case '|':
if ((c = nextc(true)) == '|') {
yylval = GET_INSTRUCTION(Op_or);
- allow_newline();
+ INSTRUCTION *new_comment = NULL;
+ allow_newline(& new_comment);
+ yylval->comment = new_comment;
+
return lasttok = LEX_OR;
} else if (! do_traditional && c == '&') {
yylval = GET_INSTRUCTION(Op_symbol);
yylval->redir_type = redirect_twoway;
+
return lasttok = (in_print && in_parens == 0 ? IO_OUT : IO_IN);
}
pushback();
@@ -4260,8 +4384,11 @@ out:
yylval->lextok = tokkey;
#define SMART_ALECK 1
- if (SMART_ALECK && do_lint
- && ! goto_warned && strcasecmp(tokkey, "goto") == 0) {
+ if (SMART_ALECK
+ && do_lint
+ && ! goto_warned
+ && tolower(tokkey[0]) == 'g'
+ && strcasecmp(tokkey, "goto") == 0) {
goto_warned = true;
lintwarn(_("`goto' considered harmful!"));
}
@@ -4442,10 +4569,20 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push)
arg->nexti->opcode = Op_push_arg; /* argument may be array */
}
- } else if (r->builtin == do_isarray || r->builtin == do_typeof) {
+ } else if (r->builtin == do_isarray) {
+ arg = subn->nexti;
+ if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push)
+ arg->nexti->opcode = Op_push_arg_untyped; /* argument may be untyped */
+ } else if (r->builtin == do_typeof) {
arg = subn->nexti;
if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push)
arg->nexti->opcode = Op_push_arg_untyped; /* argument may be untyped */
+ if (nexp == 2) { /* 2nd argument there */
+ arg = subn->nexti->lasti->nexti; /* 2nd arg list */
+ ip = arg->lasti;
+ if (ip->opcode == Op_push)
+ ip->opcode = Op_push_array;
+ }
#ifdef SUPPLY_INTDIV
} else if (r->builtin == do_intdiv
#ifdef HAVE_MPFR
@@ -4734,13 +4871,15 @@ mk_function(INSTRUCTION *fi, INSTRUCTION *def)
/* add any pre-function comment to start of action for profile.c */
- if (function_comment != NULL) {
- function_comment->source_line = 0;
- (void) list_prepend(def, function_comment);
- function_comment = NULL;
+ if (interblock_comment != NULL) {
+ interblock_comment->source_line = 0;
+ merge_comments(interblock_comment, fi->comment);
+ fi->comment = interblock_comment;
+ interblock_comment = NULL;
}
- /* add an implicit return at end;
+ /*
+ * Add an implicit return at end;
* also used by 'return' command in debugger
*/
@@ -4748,6 +4887,11 @@ mk_function(INSTRUCTION *fi, INSTRUCTION *def)
def->lasti->memory = dupnode(Nnull_string);
(void) list_append(def, instruction(Op_K_return));
+ if (trailing_comment != NULL) {
+ (void) list_append(def, trailing_comment);
+ trailing_comment = NULL;
+ }
+
if (do_pretty_print)
(void) list_prepend(def, instruction(Op_exec_count));
@@ -4922,22 +5066,19 @@ check_funcs()
for (i = 0; i < HASHSIZE; i++) {
for (fp = ftable[i]; fp != NULL; fp = fp->next) {
-#ifdef REALLYMEAN
- /* making this the default breaks old code. sigh. */
- if (fp->defined == 0 && ! fp->extension) {
- error(
- _("function `%s' called but never defined"), fp->name);
- errcount++;
- }
-#else
- if (do_lint && fp->defined == 0 && ! fp->extension)
- lintwarn(
- _("function `%s' called but never defined"), fp->name);
-#endif
+ if (do_lint && ! fp->extension) {
+ /*
+ * Making this not a lint check and
+ * incrementing * errcount breaks old code.
+ * Sigh.
+ */
+ if (fp->defined == 0)
+ lintwarn(_("function `%s' called but never defined"),
+ fp->name);
- if (do_lint && fp->used == 0 && ! fp->extension) {
- lintwarn(_("function `%s' defined but never called directly"),
- fp->name);
+ if (fp->used == 0)
+ lintwarn(_("function `%s' defined but never called directly"),
+ fp->name);
}
}
}
@@ -5454,12 +5595,11 @@ append_rule(INSTRUCTION *pattern, INSTRUCTION *action)
(rp + 1)->lasti = action->lasti;
(rp + 2)->first_line = pattern->source_line;
(rp + 2)->last_line = lastline;
- if (block_comment != NULL) {
- ip = list_prepend(list_prepend(action, block_comment), rp);
- block_comment = NULL;
- } else
- ip = list_prepend(action, rp);
-
+ ip = list_prepend(action, rp);
+ if (interblock_comment != NULL) {
+ ip = list_prepend(ip, interblock_comment);
+ interblock_comment = NULL;
+ }
} else {
rp = bcalloc(Op_rule, 3, 0);
rp->in_rule = Rule;
@@ -5485,14 +5625,20 @@ append_rule(INSTRUCTION *pattern, INSTRUCTION *action)
(rp + 2)->last_line = find_line(pattern, LAST_LINE);
action = list_create(instruction(Op_K_print_rec));
if (do_pretty_print)
- (void) list_prepend(action, instruction(Op_exec_count));
+ action = list_prepend(action, instruction(Op_exec_count));
} else
(rp + 2)->last_line = lastline;
+ if (interblock_comment != NULL) { // was after previous action
+ pattern = list_prepend(pattern, interblock_comment);
+ interblock_comment = NULL;
+ }
+
if (do_pretty_print) {
- (void) list_prepend(pattern, instruction(Op_exec_count));
- (void) list_prepend(action, instruction(Op_exec_count));
+ pattern = list_prepend(pattern, instruction(Op_exec_count));
+ action = list_prepend(action, instruction(Op_exec_count));
}
+
(rp + 1)->firsti = action->nexti;
(rp + 1)->lasti = tp;
ip = list_append(
@@ -5864,8 +6010,9 @@ mk_for_loop(INSTRUCTION *forp, INSTRUCTION *init, INSTRUCTION *cond,
forp->target_break = tbreak;
forp->target_continue = tcont;
ret = list_prepend(ret, forp);
- } /* else
- forp is NULL */
+ }
+ /* else
+ forp is NULL */
return ret;
}
@@ -6079,26 +6226,6 @@ list_merge(INSTRUCTION *l1, INSTRUCTION *l2)
return l1;
}
-/* add_pending_comment --- add a pending comment to a statement */
-
-static inline INSTRUCTION *
-add_pending_comment(INSTRUCTION *stmt)
-{
- INSTRUCTION *ret = stmt;
-
- if (prior_comment != NULL) {
- if (function_comment != prior_comment)
- ret = list_append(stmt, prior_comment);
- prior_comment = NULL;
- } else if (comment != NULL && comment->memory->comment_type == EOL_COMMENT) {
- if (function_comment != comment)
- ret = list_append(stmt, comment);
- comment = NULL;
- }
-
- return ret;
-}
-
/* See if name is a special token. */
int
@@ -6267,9 +6394,6 @@ install_builtins(void)
bool
is_alpha(int c)
{
-#ifdef I_DONT_KNOW_WHAT_IM_DOING
- return isalpha(c);
-#else /* ! I_DONT_KNOW_WHAT_IM_DOING */
switch (c) {
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
@@ -6284,7 +6408,6 @@ is_alpha(int c)
return true;
}
return false;
-#endif /* ! I_DONT_KNOW_WHAT_IM_DOING */
}
/* is_alnum --- return true for alphanumeric, English only letters */
@@ -6342,3 +6465,91 @@ set_profile_text(NODE *n, const char *str, size_t len)
return n;
}
+
+/*
+ * merge_comments --- merge c2 into c1 and free c2 if successful.
+ * Allow c2 to be NULL, in which case just merged chained
+ * comments in c1.
+ */
+
+static void
+merge_comments(INSTRUCTION *c1, INSTRUCTION *c2)
+{
+ assert(c1->opcode == Op_comment);
+
+ if (c1->comment == NULL && c2 == NULL) // nothing to do
+ return;
+
+ size_t total = c1->memory->stlen;
+ if (c1->comment != NULL)
+ total += 1 /* \n */ + c1->comment->memory->stlen;
+
+ if (c2 != NULL) {
+ assert(c2->opcode == Op_comment);
+ total += 1 /* \n */ + c2->memory->stlen;
+ if (c2->comment != NULL)
+ total += c2->comment->memory->stlen + 1;
+ }
+
+ char *buffer;
+ emalloc(buffer, char *, total + 1, "merge_comments");
+
+ strcpy(buffer, c1->memory->stptr);
+ if (c1->comment != NULL) {
+ strcat(buffer, "\n");
+ strcat(buffer, c1->comment->memory->stptr);
+ }
+
+ if (c2 != NULL) {
+ strcat(buffer, "\n");
+ strcat(buffer, c2->memory->stptr);
+ if (c2->comment != NULL) {
+ strcat(buffer, "\n");
+ strcat(buffer, c2->comment->memory->stptr);
+ }
+
+ unref(c2->memory);
+ if (c2->comment != NULL) {
+ unref(c2->comment->memory);
+ bcfree(c2->comment);
+ c2->comment = NULL;
+ }
+ bcfree(c2);
+ }
+
+ c1->memory->comment_type = BLOCK_COMMENT;
+ free(c1->memory->stptr);
+ c1->memory->stptr = buffer;
+ c1->memory->stlen = strlen(buffer);
+
+ // now free everything else
+ if (c1->comment != NULL) {
+ unref(c1->comment->memory);
+ bcfree(c1->comment);
+ c1->comment = NULL;
+ }
+}
+
+/* make_braced_statements --- handle `l_brace statements r_brace' with comments */
+
+static INSTRUCTION *
+make_braced_statements(INSTRUCTION *lbrace, INSTRUCTION *stmts, INSTRUCTION *rbrace)
+{
+ INSTRUCTION *ip;
+
+ if (stmts == NULL)
+ ip = list_create(instruction(Op_no_op));
+ else
+ ip = stmts;
+
+ if (lbrace != NULL) {
+ INSTRUCTION *comment2 = lbrace->comment;
+ if (comment2 != NULL) {
+ ip = list_prepend(ip, comment2);
+ lbrace->comment = NULL;
+ }
+ ip = list_prepend(ip, lbrace);
+ }
+
+ return ip;
+}