aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--awkgram.y81
-rw-r--r--profile.c31
2 files changed, 96 insertions, 16 deletions
diff --git a/awkgram.y b/awkgram.y
index 1cf22987..54f298a6 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -87,6 +87,7 @@ 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);
+void split_comment(void);
static bool want_source = false;
static bool want_regexp = false; /* lexical scanning kludge */
@@ -147,6 +148,10 @@ static INSTRUCTION *ip_endfile;
static INSTRUCTION *ip_beginfile;
static INSTRUCTION *comment = NULL;
+static INSTRUCTION *comment0 = NULL;
+static INSTRUCTION *commentf = NULL;
+
+static int func_first = 1;
static inline INSTRUCTION *list_create(INSTRUCTION *x);
static inline INSTRUCTION *list_append(INSTRUCTION *l, INSTRUCTION *x);
@@ -335,6 +340,7 @@ pattern
| LEX_BEGIN
{
static int begin_seen = 0;
+ func_first = 0;
INSTRUCTION *ip;
if (do_lint_old && ++begin_seen == 2)
warning_ln($1->source_line,
@@ -347,6 +353,7 @@ pattern
| LEX_END
{
static int end_seen = 0;
+ func_first = 0;
if (do_lint_old && ++end_seen == 2)
warning_ln($1->source_line,
_("old awk does not support multiple `BEGIN' or `END' rules"));
@@ -357,12 +364,14 @@ pattern
}
| LEX_BEGINFILE
{
+ func_first = 0;
$1->in_rule = rule = BEGINFILE;
$1->source_file = source;
$$ = $1;
}
| LEX_ENDFILE
{
+ func_first = 0;
$1->in_rule = rule = ENDFILE;
$1->source_file = source;
$$ = $1;
@@ -404,6 +413,16 @@ lex_builtin
function_prologue
: LEX_FUNCTION func_name '(' 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 (comment != NULL && func_first && strstr(comment->memory->stptr, "\n\n") != NULL)
+ split_comment();
+ /* save any other pre-function comment as function comment */
+ if (comment != NULL){
+ commentf = comment;
+ comment = NULL;
+ }
+ func_first = 0;
$1->source_file = source;
if (install_function($2->lextok, $1, $4) < 0)
YYABORT;
@@ -461,14 +480,19 @@ a_slash
statements
: /* empty */
- { $$ = NULL; }
+ {
+ if (comment != NULL){
+ $$ = list_create(comment);
+ comment = NULL;
+ } else $$ = NULL;
+ }
| statements statement
{
if ($2 == NULL) {
if (comment == NULL)
$$ = $1;
else {
- $$ = list_prepend($1, comment);
+ $$ = list_append($1, comment);
comment = NULL;
}
} else {
@@ -477,12 +501,12 @@ statements
if (comment == NULL)
$$ = $2;
else {
- $$ = list_prepend($2, comment);
+ $$ = list_append($2, comment);
comment = NULL;
}
} else {
if (comment != NULL){
- list_prepend($2, comment);
+ list_append($2, comment);
comment = NULL;
}
$$ = list_merge($1, $2);
@@ -2289,8 +2313,12 @@ mk_program()
if (begin_block != NULL)
cp = list_merge(begin_block, cp);
- if (comment != NULL)
+ if (comment0 != NULL){
+ (void) list_prepend(cp, comment0);
+ }
+ if (comment != NULL){
(void) list_append(cp, comment);
+ }
(void) list_append(cp, ip_atexit);
(void) list_append(cp, instruction(Op_stop));
@@ -2969,8 +2997,10 @@ pushback(void)
int get_comment(void)
{
int c;
+ int sl;
tok = tokstart;
tokadd('#');
+ sl = sourceline;
while (true){
while ((c = nextc(false)) != '\n' && c != END_FILE){
@@ -2996,13 +3026,44 @@ int get_comment(void)
} else
break;
}
- comment = bcalloc(Op_comment, 1, sourceline);
+ comment = bcalloc(Op_comment, 1, sl);
comment->source_file = source;
comment->memory = make_str_node(tokstart, tok - tokstart, 0);
return c;
}
+/* split_comment --- split initial comment text into program and function parts */
+
+void split_comment(void)
+{
+ char *p;
+ int l;
+ int j;
+ NODE *n;
+
+ p = comment->memory->stptr;
+ l = comment->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'){
+ commentf = comment;
+ n = commentf->memory;
+ commentf->memory = make_str_node(p + l + 2, n->stlen - l - 2, 0);
+ /* create program comment */
+ comment0 = bcalloc(Op_comment, 1, sourceline);
+ comment0->source_file = comment->source_file;
+ p[l + 2] = 0;
+ comment0->memory = make_str_node(p , l + 2, 0);
+ comment = NULL;
+ freenode(n);
+ break;
+ }
+ else l--;
+ }
+
+}
+
/* allow_newline --- allow newline after &&, ||, ? and : */
static void
@@ -4331,6 +4392,14 @@ mk_function(INSTRUCTION *fi, INSTRUCTION *def)
(t + 1)->tail_call = true;
}
+ /* add any pre-function comment to start of action for profile.c */
+
+ if (commentf != NULL){
+ commentf->source_line = 0;
+ (void) list_prepend(def, commentf);
+ commentf = NULL;
+ }
+
/* add an implicit return at end;
* also used by 'return' command in debugger
*/
diff --git a/profile.c b/profile.c
index 4db29c9a..8eb31b24 100644
--- a/profile.c
+++ b/profile.c
@@ -101,10 +101,11 @@ indent(long count)
{
int i;
- if (count == 0)
- fprintf(prof_fp, "\t");
- else
- fprintf(prof_fp, "%6ld ", count);
+ if ( do_profile)
+ if (count == 0)
+ fprintf(prof_fp, "\t");
+ else
+ fprintf(prof_fp, "%6ld ", count);
assert(indent_level >= 0);
for (i = 0; i < indent_level; i++)
@@ -197,13 +198,13 @@ pprint(INSTRUCTION *startp, INSTRUCTION *endp, bool in_for_header)
if (ip->opcode == Op_comment){
/* print pre-begin/end comments */
print_comment(ip, 0);
- ip = pc->nexti->nexti;
+ ip = ip->nexti->nexti;
}
- if (! rule_count[rule]++)
+ if (do_profile && ! rule_count[rule]++)
fprintf(prof_fp, _("\t# %s block(s)\n\n"), ruletab[rule]);
fprintf(prof_fp, "\t%s {\n", ruletab[rule]);
} else {
- if (! rule_count[rule]++)
+ if (do_profile && ! rule_count[rule]++)
fprintf(prof_fp, _("\t# Rule(s)\n\n"));
ic = ip = pc->nexti;
i2 = (pc + 1)->firsti;
@@ -1015,7 +1016,8 @@ dump_prog(INSTRUCTION *code)
(void) time(& now);
/* \n on purpose, with \n in ctime() output */
- fprintf(prof_fp, _("\t# gawk profile, created %s\n"), ctime(& now));
+ if (do_profile)
+ fprintf(prof_fp, _("\t# gawk profile, created %s\n"), ctime(& now));
print_lib_list(prof_fp);
pprint(code, NULL, false);
}
@@ -1515,14 +1517,23 @@ pp_func(INSTRUCTION *pc, void *data ATTRIBUTE_UNUSED)
static bool first = true;
NODE *func;
int pcount;
+ INSTRUCTION *fp;
if (first) {
first = false;
- fprintf(prof_fp, _("\n\t# Functions, listed alphabetically\n"));
+ if (do_profile)
+ fprintf(prof_fp, _("\n\t# Functions, listed alphabetically\n"));
}
+ fp = pc->nexti->nexti;
func = pc->func_body;
fprintf(prof_fp, "\n");
+/* print any function comment */
+ if (fp->opcode == Op_comment && fp->source_line == 0){
+ print_comment(fp, 0);
+ fp = fp->nexti;
+ }
+ fprintf(prof_fp, "\t");
indent(pc->nexti->exec_count);
fprintf(prof_fp, "%s %s(", op2str(Op_K_function), func->vname);
pcount = func->param_cnt;
@@ -1534,7 +1545,7 @@ pp_func(INSTRUCTION *pc, void *data ATTRIBUTE_UNUSED)
}
fprintf(prof_fp, ")\n\t{\n");
indent_in();
- pprint(pc->nexti->nexti, NULL, false); /* function body */
+ pprint(fp, NULL, false); /* function body */
indent_out();
fprintf(prof_fp, "\t}\n");
return 0;