aboutsummaryrefslogtreecommitdiffstats
path: root/profile.c
diff options
context:
space:
mode:
Diffstat (limited to 'profile.c')
-rw-r--r--profile.c409
1 files changed, 271 insertions, 138 deletions
diff --git a/profile.c b/profile.c
index 39c4f03d..f9c7c809 100644
--- a/profile.c
+++ b/profile.c
@@ -26,17 +26,19 @@
#include "awk.h"
static void pprint(INSTRUCTION *startp, INSTRUCTION *endp, int flags);
+static INSTRUCTION *end_line(INSTRUCTION *ip);
static void pp_parenthesize(NODE *n);
static void parenthesize(int type, NODE *left, NODE *right);
static char *pp_list(int nargs, const char *paren, const char *delim);
static char *pp_group3(const char *s1, const char *s2, const char *s3);
static char *pp_concat(int nargs);
+static char *pp_string_or_strong_regex(const char *in_str, size_t len, int delim, bool strong_regex);
static bool is_binary(int type);
static bool is_scalar(int type);
static int prec_level(int type);
static void pp_push(int type, char *s, int flag);
static NODE *pp_pop(void);
-static void pp_free(NODE *n);
+static void print_comment(INSTRUCTION *pc, long in);
const char *redir2str(int redirtype);
#define pp_str vname
@@ -46,8 +48,8 @@ const char *redir2str(int redirtype);
#define DONT_FREE 1
#define CAN_FREE 2
-static RETSIGTYPE dump_and_exit(int signum) ATTRIBUTE_NORETURN;
-static RETSIGTYPE just_dump(int signum);
+static void dump_and_exit(int signum) ATTRIBUTE_NORETURN;
+static void just_dump(int signum);
/* pretty printing related functions and variables */
@@ -123,10 +125,12 @@ 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++)
@@ -196,52 +200,94 @@ pprint(INSTRUCTION *startp, INSTRUCTION *endp, int flags)
NODE *t1;
char *str;
NODE *t2;
- INSTRUCTION *ip;
+ INSTRUCTION *ip1;
+ INSTRUCTION *ip2;
NODE *m;
char *tmp;
int rule;
static int rule_count[MAXRULE];
+ static bool skip_comment = false;
for (pc = startp; pc != endp; pc = pc->nexti) {
if (pc->source_line > 0)
sourceline = pc->source_line;
+ /* skip leading EOL comment as it has already been printed */
+ if (pc->opcode == Op_comment
+ && pc->memory->comment_type == EOL_COMMENT
+ && skip_comment) {
+ skip_comment = false;
+ continue;
+ }
+ skip_comment = false;
+
switch (pc->opcode) {
case Op_rule:
+ /*
+ * Rules are three instructions long.
+ * See append_rule in awkgram.y.
+ * The first has the Rule Op Code, nexti etc.
+ * The second, (pc + 1) has firsti and lasti:
+ * the first/last ACTION instructions for this rule.
+ * The third has first_line and last_line:
+ * the first and last source line numbers.
+ */
source = pc->source_file;
rule = pc->in_rule;
if (rule != Rule) {
- if (! rule_count[rule]++)
- fprintf(prof_fp, _("\t# %s rule(s)\n\n"), ruletab[rule]);
- fprintf(prof_fp, "\t%s {\n", ruletab[rule]);
- ip = (pc + 1)->firsti;
+ /* Allow for pre-non-rule-block comment */
+ if (pc->nexti != (pc +1)->firsti
+ && pc->nexti->opcode == Op_comment
+ && pc->nexti->memory->comment_type == FULL_COMMENT)
+ print_comment(pc->nexti, -1);
+ ip1 = (pc + 1)->firsti;
+ ip2 = (pc + 1)->lasti;
+
+ if (do_profile) {
+ if (! rule_count[rule]++)
+ fprintf(prof_fp, _("\t# %s rule(s)\n\n"), ruletab[rule]);
+ indent(0);
+ }
+ fprintf(prof_fp, "%s {", ruletab[rule]);
+ end_line(pc);
+ skip_comment = true;
} else {
- if (! rule_count[rule]++)
+ if (do_profile && ! rule_count[rule]++)
fprintf(prof_fp, _("\t# Rule(s)\n\n"));
- ip = pc->nexti;
- indent(ip->exec_count);
- if (ip != (pc + 1)->firsti) { /* non-empty pattern */
- pprint(ip->nexti, (pc + 1)->firsti, NO_PPRINT_FLAGS);
- t1 = pp_pop();
- fprintf(prof_fp, "%s {", t1->pp_str);
- pp_free(t1);
- ip = (pc + 1)->firsti;
-
- if (do_profile && ip->exec_count > 0)
- fprintf(prof_fp, " # %ld", ip->exec_count);
-
- fprintf(prof_fp, "\n");
+ ip1 = pc->nexti;
+ indent(ip1->exec_count);
+ if (ip1 != (pc + 1)->firsti) { /* non-empty pattern */
+ pprint(ip1->nexti, (pc + 1)->firsti, NO_PPRINT_FLAGS);
+ /* Allow for case where the "pattern" is just a comment */
+ if (ip1->nexti->nexti->nexti != (pc +1)->firsti
+ || ip1->nexti->opcode != Op_comment) {
+ t1 = pp_pop();
+ fprintf(prof_fp, "%s {", t1->pp_str);
+ pp_free(t1);
+ } else
+ fprintf(prof_fp, "{");
+ ip1 = (pc + 1)->firsti;
+ ip2 = (pc + 1)->lasti;
+
+ if (do_profile && ip1->exec_count > 0)
+ fprintf(prof_fp, " # %ld", ip1->exec_count);
+
+ end_line(ip1);
+ skip_comment = true;
} else {
fprintf(prof_fp, "{\n");
- ip = (pc + 1)->firsti;
+ ip1 = (pc + 1)->firsti;
+ ip2 = (pc + 1)->lasti;
}
- ip = ip->nexti;
+ ip1 = ip1->nexti;
}
indent_in();
- pprint(ip, (pc + 1)->lasti, NO_PPRINT_FLAGS);
+ pprint(ip1, ip2, NO_PPRINT_FLAGS);
indent_out();
- fprintf(prof_fp, "\t}\n\n");
+ if (do_profile)
+ indent(0);
+ fprintf(prof_fp, "}\n\n");
pc = (pc + 1)->lasti;
break;
@@ -280,6 +326,7 @@ pprint(INSTRUCTION *startp, INSTRUCTION *endp, int flags)
case Op_push_array:
case Op_push:
case Op_push_arg:
+ case Op_push_arg_untyped:
m = pc->memory;
switch (m->type) {
case Node_param_list:
@@ -326,7 +373,7 @@ cleanup:
pp_free(t2);
pp_free(t1);
if ((flags & IN_FOR_HEADER) == 0)
- fprintf(prof_fp, "\n");
+ pc = end_line(pc);
break;
default:
@@ -416,10 +463,13 @@ cleanup:
case Op_field_spec:
case Op_field_spec_lhs:
case Op_unary_minus:
+ case Op_unary_plus:
case Op_not:
t1 = pp_pop();
if (is_binary(t1->type)
- || (((OPCODE) t1->type) == pc->opcode && pc->opcode == Op_unary_minus))
+ || (((OPCODE) t1->type) == pc->opcode
+ && (pc->opcode == Op_unary_minus
+ || pc->opcode == Op_unary_plus)))
pp_parenthesize(t1);
/* optypes table (eval.c) includes space after ! */
@@ -452,7 +502,7 @@ cleanup:
pp_free(t2);
pp_free(t1);
if ((flags & IN_FOR_HEADER) == 0)
- fprintf(prof_fp, "\n");
+ pc = end_line(pc);
break;
case Op_concat:
@@ -473,7 +523,7 @@ cleanup:
} else
fprintf(prof_fp, "%s %s", op2str(Op_K_delete), array);
if ((flags & IN_FOR_HEADER) == 0)
- fprintf(prof_fp, "\n");
+ pc = end_line(pc);
pp_free(t1);
}
break;
@@ -585,7 +635,7 @@ cleanup:
fprintf(prof_fp, "%s%s", op2str(pc->opcode), tmp);
efree(tmp);
if ((flags & IN_FOR_HEADER) == 0)
- fprintf(prof_fp, "\n");
+ pc = end_line(pc);
break;
case Op_push_re:
@@ -686,7 +736,8 @@ cleanup:
case Op_K_break:
case Op_K_nextfile:
case Op_K_next:
- fprintf(prof_fp, "%s\n", op2str(pc->opcode));
+ fprintf(prof_fp, "%s", op2str(pc->opcode));
+ pc = end_line(pc);
break;
case Op_K_return:
@@ -694,8 +745,10 @@ cleanup:
t1 = pp_pop();
if (is_binary(t1->type))
pp_parenthesize(t1);
- if (pc->source_line > 0) /* don't print implicit 'return' at end of function */
- fprintf(prof_fp, "%s %s\n", op2str(pc->opcode), t1->pp_str);
+ if (pc->source_line > 0) { /* don't print implicit 'return' at end of function */
+ fprintf(prof_fp, "%s %s", op2str(pc->opcode), t1->pp_str);
+ pc = end_line(pc);
+ }
pp_free(t1);
break;
@@ -703,73 +756,78 @@ cleanup:
t1 = pp_pop();
fprintf(prof_fp, "%s", t1->pp_str);
if ((flags & IN_FOR_HEADER) == 0)
- fprintf(prof_fp, "\n");
+ pc = end_line(pc);
pp_free(t1);
break;
case Op_line_range:
- ip = pc + 1;
- pprint(pc->nexti, ip->condpair_left, NO_PPRINT_FLAGS);
- pprint(ip->condpair_left->nexti, ip->condpair_right, NO_PPRINT_FLAGS);
+ ip1 = pc + 1;
+ pprint(pc->nexti, ip1->condpair_left, NO_PPRINT_FLAGS);
+ pprint(ip1->condpair_left->nexti, ip1->condpair_right, NO_PPRINT_FLAGS);
t2 = pp_pop();
t1 = pp_pop();
str = pp_group3(t1->pp_str, ", ", t2->pp_str);
pp_free(t1);
pp_free(t2);
pp_push(Op_line_range, str, CAN_FREE);
- pc = ip->condpair_right;
+ pc = ip1->condpair_right;
break;
case Op_K_while:
- ip = pc + 1;
- indent(ip->while_body->exec_count);
+ ip1 = pc + 1;
+ indent(ip1->while_body->exec_count);
fprintf(prof_fp, "%s (", op2str(pc->opcode));
- pprint(pc->nexti, ip->while_body, NO_PPRINT_FLAGS);
+ pprint(pc->nexti, ip1->while_body, NO_PPRINT_FLAGS);
t1 = pp_pop();
- fprintf(prof_fp, "%s) {\n", t1->pp_str);
+ fprintf(prof_fp, "%s) {", t1->pp_str);
pp_free(t1);
+ ip1->while_body = end_line(ip1->while_body);
indent_in();
- pprint(ip->while_body->nexti, pc->target_break, NO_PPRINT_FLAGS);
+ pprint(ip1->while_body->nexti, pc->target_break, NO_PPRINT_FLAGS);
indent_out();
indent(SPACEOVER);
- fprintf(prof_fp, "}\n");
- pc = pc->target_break;
+ fprintf(prof_fp, "}");
+ pc = end_line(pc->target_break);
break;
case Op_K_do:
- ip = pc + 1;
+ ip1 = pc + 1;
indent(pc->nexti->exec_count);
- fprintf(prof_fp, "%s {\n", op2str(pc->opcode));
+ fprintf(prof_fp, "%s {", op2str(pc->opcode));
+ end_line(pc->nexti);
+ skip_comment = true;
indent_in();
- pprint(pc->nexti->nexti, ip->doloop_cond, NO_PPRINT_FLAGS);
+ pprint(pc->nexti->nexti, ip1->doloop_cond, NO_PPRINT_FLAGS);
indent_out();
- pprint(ip->doloop_cond, pc->target_break, NO_PPRINT_FLAGS);
+ pprint(ip1->doloop_cond, pc->target_break, NO_PPRINT_FLAGS);
indent(SPACEOVER);
t1 = pp_pop();
- fprintf(prof_fp, "} %s (%s)\n", op2str(Op_K_while), t1->pp_str);
+ fprintf(prof_fp, "} %s (%s)", op2str(Op_K_while), t1->pp_str);
pp_free(t1);
+ end_line(pc->target_break);
+ skip_comment = true;
pc = pc->target_break;
break;
case Op_K_for:
- ip = pc + 1;
- indent(ip->forloop_body->exec_count);
+ ip1 = pc + 1;
+ indent(ip1->forloop_body->exec_count);
fprintf(prof_fp, "%s (", op2str(pc->opcode));
/* If empty for looop header, print it a little more nicely. */
if ( pc->nexti->opcode == Op_no_op
- && ip->forloop_cond == pc->nexti
+ && ip1->forloop_cond == pc->nexti
&& pc->target_continue->opcode == Op_jmp) {
fprintf(prof_fp, ";;");
} else {
- pprint(pc->nexti, ip->forloop_cond, IN_FOR_HEADER);
+ pprint(pc->nexti, ip1->forloop_cond, IN_FOR_HEADER);
fprintf(prof_fp, "; ");
- if (ip->forloop_cond->opcode == Op_no_op &&
- ip->forloop_cond->nexti == ip->forloop_body)
+ if (ip1->forloop_cond->opcode == Op_no_op &&
+ ip1->forloop_cond->nexti == ip1->forloop_body)
fprintf(prof_fp, "; ");
else {
- pprint(ip->forloop_cond, ip->forloop_body, IN_FOR_HEADER);
+ pprint(ip1->forloop_cond, ip1->forloop_body, IN_FOR_HEADER);
t1 = pp_pop();
fprintf(prof_fp, "%s; ", t1->pp_str);
pp_free(t1);
@@ -777,12 +835,16 @@ cleanup:
pprint(pc->target_continue, pc->target_break, IN_FOR_HEADER);
}
- fprintf(prof_fp, ") {\n");
+ fprintf(prof_fp, ") {");
+ end_line(ip1->forloop_body);
+ skip_comment = true;
indent_in();
- pprint(ip->forloop_body->nexti, pc->target_continue, NO_PPRINT_FLAGS);
+ pprint(ip1->forloop_body->nexti, pc->target_continue, NO_PPRINT_FLAGS);
indent_out();
indent(SPACEOVER);
- fprintf(prof_fp, "}\n");
+ fprintf(prof_fp, "}");
+ end_line(pc->target_break);
+ skip_comment = true;
pc = pc->target_break;
break;
@@ -791,35 +853,39 @@ cleanup:
char *array;
const char *item;
- ip = pc + 1;
+ ip1 = pc + 1;
t1 = pp_pop();
array = t1->pp_str;
- m = ip->forloop_cond->array_var;
+ m = ip1->forloop_cond->array_var;
if (m->type == Node_param_list)
item = func_params[m->param_cnt].param;
else
item = m->vname;
- indent(ip->forloop_body->exec_count);
- fprintf(prof_fp, "%s (%s%s%s) {\n", op2str(Op_K_arrayfor),
+ indent(ip1->forloop_body->exec_count);
+ fprintf(prof_fp, "%s (%s%s%s) {", op2str(Op_K_arrayfor),
item, op2str(Op_in_array), array);
+ end_line(ip1->forloop_body);
+ skip_comment = true;
indent_in();
pp_free(t1);
- pprint(ip->forloop_body->nexti, pc->target_break, NO_PPRINT_FLAGS);
+ pprint(ip1->forloop_body->nexti, pc->target_break, NO_PPRINT_FLAGS);
indent_out();
indent(SPACEOVER);
- fprintf(prof_fp, "}\n");
+ fprintf(prof_fp, "}");
+ end_line(pc->target_break);
+ skip_comment = true;
pc = pc->target_break;
}
break;
case Op_K_switch:
- ip = pc + 1;
+ ip1 = pc + 1;
fprintf(prof_fp, "%s (", op2str(pc->opcode));
- pprint(pc->nexti, ip->switch_start, NO_PPRINT_FLAGS);
+ pprint(pc->nexti, ip1->switch_start, NO_PPRINT_FLAGS);
t1 = pp_pop();
fprintf(prof_fp, "%s) {\n", t1->pp_str);
pp_free(t1);
- pprint(ip->switch_start, ip->switch_end, NO_PPRINT_FLAGS);
+ pprint(ip1->switch_start, ip1->switch_end, NO_PPRINT_FLAGS);
indent(SPACEOVER);
fprintf(prof_fp, "}\n");
pc = pc->target_break;
@@ -830,10 +896,13 @@ cleanup:
indent(pc->stmt_start->exec_count);
if (pc->opcode == Op_K_case) {
t1 = pp_pop();
- fprintf(prof_fp, "%s %s:\n", op2str(pc->opcode), t1->pp_str);
+ fprintf(prof_fp, "%s %s:", op2str(pc->opcode), t1->pp_str);
+ pc = end_line(pc);
pp_free(t1);
- } else
- fprintf(prof_fp, "%s:\n", op2str(pc->opcode));
+ } else {
+ fprintf(prof_fp, "%s:", op2str(pc->opcode));
+ pc = end_line(pc);
+ }
indent_in();
pprint(pc->stmt_start->nexti, pc->stmt_end->nexti, NO_PPRINT_FLAGS);
indent_out();
@@ -846,17 +915,22 @@ cleanup:
fprintf(prof_fp, "%s) {", t1->pp_str);
pp_free(t1);
- ip = pc->branch_if;
- if (ip->exec_count > 0)
- fprintf(prof_fp, " # %ld", ip->exec_count);
- fprintf(prof_fp, "\n");
+ ip1 = pc->branch_if;
+ if (ip1->exec_count > 0)
+ fprintf(prof_fp, " # %ld", ip1->exec_count);
+ ip1 = end_line(ip1);
indent_in();
- pprint(ip->nexti, pc->branch_else, NO_PPRINT_FLAGS);
+ pprint(ip1->nexti, pc->branch_else, NO_PPRINT_FLAGS);
indent_out();
pc = pc->branch_else;
if (pc->nexti->opcode == Op_no_op) { /* no following else */
indent(SPACEOVER);
- fprintf(prof_fp, "}\n");
+ fprintf(prof_fp, "}");
+ if (pc->nexti->nexti->opcode != Op_comment
+ || pc->nexti->nexti->memory->comment_type == FULL_COMMENT)
+ fprintf(prof_fp, "\n");
+ /* else
+ It will be printed at the top. */
}
/*
* See next case; turn off the flag so that the
@@ -885,13 +959,22 @@ cleanup:
&& pc->branch_end == pc->nexti->nexti->branch_else->lasti) {
pprint(pc->nexti, pc->branch_end, IN_ELSE_IF);
} else {
- fprintf(prof_fp, "{\n");
+ fprintf(prof_fp, "{");
+ end_line(pc);
+ skip_comment = true;
indent_in();
pprint(pc->nexti, pc->branch_end, NO_PPRINT_FLAGS);
indent_out();
indent(SPACEOVER);
- fprintf(prof_fp, "}\n");
+ fprintf(prof_fp, "}");
+ end_line(pc->branch_end);
+ skip_comment = true;
}
+ /*
+ * Don't do end_line() here, we get multiple blank lines after
+ * the final else in a chain of else-ifs since they all point
+ * to the same branch_end.
+ */
pc = pc->branch_end;
break;
@@ -901,11 +984,11 @@ cleanup:
size_t len;
pprint(pc->nexti, pc->branch_if, NO_PPRINT_FLAGS);
- ip = pc->branch_if;
- pprint(ip->nexti, pc->branch_else, NO_PPRINT_FLAGS);
- ip = pc->branch_else->nexti;
+ ip1 = pc->branch_if;
+ pprint(ip1->nexti, pc->branch_else, NO_PPRINT_FLAGS);
+ ip1 = pc->branch_else->nexti;
- pc = ip->nexti;
+ pc = ip1->nexti;
assert(pc->opcode == Op_cond_exp);
pprint(pc->nexti, pc->branch_end, NO_PPRINT_FLAGS);
@@ -930,6 +1013,13 @@ cleanup:
indent(pc->exec_count);
break;
+ case Op_comment:
+ print_comment(pc, 0);
+ break;
+
+ case Op_list:
+ break;
+
default:
cant_happen();
}
@@ -939,6 +1029,25 @@ cleanup:
}
}
+/* end_line --- end pretty print line with new line or on-line comment */
+
+INSTRUCTION *
+end_line(INSTRUCTION *ip)
+{
+ INSTRUCTION *ret = ip;
+
+ if (ip->nexti->opcode == Op_comment
+ && ip->nexti->memory->comment_type == EOL_COMMENT) {
+ fprintf(prof_fp, "\t");
+ print_comment(ip->nexti, -1);
+ ret = ip->nexti;
+ }
+ else
+ fprintf(prof_fp, "\n");
+
+ return ret;
+}
+
/* pp_string_fp --- printy print a string to the fp */
/*
@@ -970,7 +1079,7 @@ pp_string_fp(Func_print print_func, FILE *fp, const char *in_str,
/* just_dump --- dump the profile and function stack and keep going */
-static RETSIGTYPE
+static void
just_dump(int signum)
{
extern INSTRUCTION *code_block;
@@ -984,7 +1093,7 @@ just_dump(int signum)
/* dump_and_exit --- dump the profile, the function stack, and exit */
-static RETSIGTYPE
+static void
dump_and_exit(int signum)
{
just_dump(signum);
@@ -1012,6 +1121,31 @@ print_lib_list(FILE *prof_fp)
fprintf(prof_fp, "\n");
}
+/* print_comment --- print comment text with proper indentation */
+
+static void
+print_comment(INSTRUCTION* pc, long in)
+{
+ char *text;
+ size_t count;
+ bool after_newline = false;
+
+ count = pc->memory->stlen;
+ text = pc->memory->stptr;
+
+ if (in >= 0)
+ indent(in); /* is this correct? Where should comments go? */
+ for (; count > 0; count--, text++) {
+ if (after_newline) {
+ indent(in);
+ after_newline = false;
+ }
+ putc(*text, prof_fp);
+ if (*text == '\n')
+ after_newline = true;
+ }
+}
+
/* dump_prog --- dump the program */
/*
@@ -1026,7 +1160,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, NO_PPRINT_FLAGS);
}
@@ -1066,6 +1201,7 @@ prec_level(int type)
return 13;
case Op_unary_minus:
+ case Op_unary_plus:
case Op_not:
return 12;
@@ -1152,6 +1288,7 @@ is_scalar(int type)
case Op_postincrement:
case Op_postdecrement:
case Op_unary_minus:
+ case Op_unary_plus:
case Op_not:
return true;
@@ -1265,11 +1402,20 @@ parenthesize(int type, NODE *left, NODE *right)
pp_parenthesize(right);
}
-/* pp_string --- pretty format a string or regex constant */
+/* pp_string --- pretty format a string or regular regex constant */
char *
pp_string(const char *in_str, size_t len, int delim)
{
+ return pp_string_or_strong_regex(in_str, len, delim, false);
+}
+
+
+/* pp_string_or_strong_regex --- pretty format a string, regex, or hard regex constant */
+
+char *
+pp_string_or_strong_regex(const char *in_str, size_t len, int delim, bool strong_regex)
+{
static char str_escapes[] = "\a\b\f\n\r\t\v\\";
static char str_printables[] = "abfnrtv\\";
static char re_escapes[] = "\a\b\f\n\r\t\v";
@@ -1301,7 +1447,8 @@ pp_string(const char *in_str, size_t len, int delim)
osiz *= 2; \
} ofre -= (l)
- osiz = len + 3 + 2; /* initial size; 3 for delim + terminating null */
+ /* initial size; 3 for delim + terminating null, 1 for @ */
+ osiz = len + 3 + 1 + (strong_regex == true);
emalloc(obuf, char *, osiz, "pp_string");
obufout = obuf;
ofre = osiz - 1;
@@ -1313,10 +1460,9 @@ pp_string(const char *in_str, size_t len, int delim)
*obufout++ = '\\';
*obufout++ = delim;
} else if (*str == '\0') {
- chksize(4);
-
*obufout++ = '\\';
*obufout++ = '0';
+ chksize(2); /* need 2 more chars for this case */
*obufout++ = '0';
*obufout++ = '0';
} else if ((cp = strchr(escapes, *str)) != NULL) {
@@ -1326,7 +1472,7 @@ pp_string(const char *in_str, size_t len, int delim)
/* NB: Deliberate use of lower-case versions. */
} else if (isascii(*str) && isprint(*str)) {
*obufout++ = *str;
- ofre += 1;
+ ofre += 1; /* used 1 less than expected */
} else {
size_t len;
@@ -1350,45 +1496,12 @@ pp_string(const char *in_str, size_t len, int delim)
char *
pp_number(NODE *n)
{
-#define PP_PRECISION 6
char *str;
-#ifdef HAVE_MPFR
- size_t count;
-
- if (is_mpg_float(n)) {
- count = mpfr_get_prec(n->mpg_numbr) / 3; /* ~ 3.22 binary digits per decimal digit */
- emalloc(str, char *, count, "pp_number");
- /*
- * 3/2015: Format string used to be "%0.*R*g". That padded
- * with leading zeros. But it doesn't do that for regular
- * numbers in the non-MPFR case.
- */
- mpfr_sprintf(str, "%.*R*g", PP_PRECISION, ROUND_MODE, n->mpg_numbr);
- } else if (is_mpg_integer(n)) {
- count = mpz_sizeinbase(n->mpg_i, 10) + 2; /* +1 for sign, +1 for NUL at end */
- emalloc(str, char *, count, "pp_number");
- mpfr_sprintf(str, "%Zd", n->mpg_i);
- } else
-#endif
- {
- /* Use format_val() to get integral values printed as integers */
- NODE *s;
-
- getnode(s);
- *s = *n;
- s->flags &= ~STRCUR;
-
- s = r_format_val("%.6g", 0, s);
-
- s->stptr[s->stlen] = '\0';
- str = s->stptr;
-
- freenode(s);
- }
-
+ assert((n->flags & NUMCONSTSTR) != 0);
+ emalloc(str, char *, n->stlen + 1, "pp_number");
+ strcpy(str, n->stptr);
return str;
-#undef PP_PRECISION
}
/* pp_node --- pretty format a node */
@@ -1566,7 +1679,7 @@ pp_group3(const char *s1, const char *s2, const char *s3)
len1 = strlen(s1);
len2 = strlen(s2);
len3 = strlen(s3);
- l = len1 + len2 + len3 + 2;
+ l = len1 + len2 + len3 + 1;
emalloc(str, char *, l, "pp_group3");
s = str;
if (len1 > 0) {
@@ -1594,14 +1707,24 @@ 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, -1); /* -1 ==> don't indent */
+ fp = fp->nexti;
+ }
+
indent(pc->nexti->exec_count);
fprintf(prof_fp, "%s %s(", op2str(Op_K_function), func->vname);
pcount = func->param_cnt;
@@ -1611,11 +1734,21 @@ pp_func(INSTRUCTION *pc, void *data ATTRIBUTE_UNUSED)
if (j < pcount - 1)
fprintf(prof_fp, ", ");
}
- fprintf(prof_fp, ")\n\t{\n");
+ if (fp->opcode == Op_comment
+ && fp->memory->comment_type == EOL_COMMENT) {
+ fprintf(prof_fp, ")");
+ fp = end_line(fp);
+ } else
+ fprintf(prof_fp, ")\n");
+ if (do_profile)
+ indent(0);
+ fprintf(prof_fp, "{\n");
indent_in();
- pprint(pc->nexti->nexti, NULL, NO_PPRINT_FLAGS); /* function body */
+ pprint(fp, NULL, NO_PPRINT_FLAGS); /* function body */
indent_out();
- fprintf(prof_fp, "\t}\n");
+ if (do_profile)
+ indent(0);
+ fprintf(prof_fp, "}\n");
return 0;
}