aboutsummaryrefslogtreecommitdiffstats
path: root/profile.c
diff options
context:
space:
mode:
Diffstat (limited to 'profile.c')
-rw-r--r--profile.c159
1 files changed, 78 insertions, 81 deletions
diff --git a/profile.c b/profile.c
index eb788377..dfac5c10 100644
--- a/profile.c
+++ b/profile.c
@@ -25,7 +25,7 @@
#include "awk.h"
-static void pprint(INSTRUCTION *startp, INSTRUCTION *endp, int in_for_header);
+static void pprint(INSTRUCTION *startp, INSTRUCTION *endp, bool in_for_header);
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);
@@ -37,21 +37,21 @@ static NODE *pp_pop(void);
static void pp_free(NODE *n);
const char *redir2str(int redirtype);
-#define pp_str hname
-#define pp_len hlength
+#define pp_str vname
+#define pp_len sub.nodep.reserved
+#define pp_next rnode
#define DONT_FREE 1
#define CAN_FREE 2
-#ifdef PROFILING
+
static RETSIGTYPE dump_and_exit(int signum) ATTRIBUTE_NORETURN;
static RETSIGTYPE just_dump(int signum);
-#endif
/* pretty printing related functions and variables */
static NODE *pp_stack = NULL;
-static char **fparms; /* function parameter names */
+static NODE *func_params; /* function parameters */
static FILE *prof_fp; /* where to send the profile */
static long indent_level = 0;
@@ -59,20 +59,7 @@ static long indent_level = 0;
#define SPACEOVER 0
-/* init_profiling --- do needed initializations, see also main.c */
-
-void
-init_profiling(int *flag ATTRIBUTE_UNUSED, const char *def_file ATTRIBUTE_UNUSED)
-{
-#ifdef PROFILING
- if (*flag == FALSE) {
- *flag = TRUE;
- set_prof_file(def_file);
- }
-#endif
-}
-
-/* set_prof_file --- set the output file for profiling */
+/* set_prof_file --- set the output file for profiling or pretty-printing */
void
set_prof_file(const char *file)
@@ -87,12 +74,11 @@ set_prof_file(const char *file)
}
}
-/* init_profiling_signals --- set up signal handling for pgawk */
+/* init_profiling_signals --- set up signal handling for gawk --profile */
void
init_profiling_signals()
{
-#ifdef PROFILING
#ifdef __DJGPP__
signal(SIGINT, dump_and_exit);
signal(SIGQUIT, just_dump);
@@ -104,7 +90,6 @@ init_profiling_signals()
signal(SIGUSR1, just_dump);
#endif
#endif /* !__DJGPP__ */
-#endif /* PROFILING */
}
/* indent --- print out enough tabs */
@@ -151,7 +136,7 @@ pp_push(int type, char *s, int flag)
n->pp_len = strlen(s);
n->flags = flag;
n->type = type;
- n->hnext = pp_stack;
+ n->pp_next = pp_stack;
pp_stack = n;
}
@@ -160,7 +145,7 @@ pp_pop()
{
NODE *n;
n = pp_stack;
- pp_stack = n->hnext;
+ pp_stack = n->pp_next;
return n;
}
@@ -177,7 +162,7 @@ pp_free(NODE *n)
*/
static void
-pprint(INSTRUCTION *startp, INSTRUCTION *endp, int in_for_header)
+pprint(INSTRUCTION *startp, INSTRUCTION *endp, bool in_for_header)
{
INSTRUCTION *pc;
NODE *t1;
@@ -209,15 +194,15 @@ pprint(INSTRUCTION *startp, INSTRUCTION *endp, int in_for_header)
ip = pc->nexti;
indent(ip->exec_count);
if (ip != (pc + 1)->firsti) { /* non-empty pattern */
- pprint(ip->nexti, (pc + 1)->firsti, FALSE);
+ pprint(ip->nexti, (pc + 1)->firsti, false);
t1 = pp_pop();
fprintf(prof_fp, "%s {", t1->pp_str);
pp_free(t1);
ip = (pc + 1)->firsti;
-#ifdef PROFILING
- if (ip->exec_count > 0)
+
+ if (do_profile && ip->exec_count > 0)
fprintf(prof_fp, " # %ld", ip->exec_count);
-#endif
+
fprintf(prof_fp, "\n");
} else {
fprintf(prof_fp, "{\n");
@@ -226,7 +211,7 @@ pprint(INSTRUCTION *startp, INSTRUCTION *endp, int in_for_header)
ip = ip->nexti;
}
indent_in();
- pprint(ip, (pc + 1)->lasti, FALSE);
+ pprint(ip, (pc + 1)->lasti, false);
indent_out();
fprintf(prof_fp, "\t}\n\n");
pc = (pc + 1)->lasti;
@@ -244,7 +229,7 @@ pprint(INSTRUCTION *startp, INSTRUCTION *endp, int in_for_header)
if (m == Nnull_string) /* optional return or exit value; don't print 0 or "" */
pp_push(pc->opcode, m->stptr, DONT_FREE);
else if ((m->flags & NUMBER) != 0)
- pp_push(pc->opcode, pp_number(m->numbr), CAN_FREE);
+ pp_push(pc->opcode, pp_number(m), CAN_FREE);
else {
str = pp_string(m->stptr, m->stlen, '"');
if ((m->flags & INTLSTR) != 0) {
@@ -257,6 +242,9 @@ pprint(INSTRUCTION *startp, INSTRUCTION *endp, int in_for_header)
break;
case Op_store_var:
+ if (pc->initval != NULL)
+ pp_push(Op_push_i, pp_node(pc->initval), CAN_FREE);
+ /* fall through */
case Op_store_sub:
case Op_assign_concat:
case Op_push_lhs:
@@ -267,7 +255,7 @@ pprint(INSTRUCTION *startp, INSTRUCTION *endp, int in_for_header)
m = pc->memory;
switch (m->type) {
case Node_param_list:
- pp_push(pc->opcode, fparms[m->param_cnt], DONT_FREE);
+ pp_push(pc->opcode, func_params[m->param_cnt].param, DONT_FREE);
break;
case Node_var:
@@ -354,7 +342,7 @@ cleanup:
&& is_binary(t1->type)) /* (a - b) * 1 */
pp_parenthesize(t1);
if ((m->flags & NUMBER) != 0)
- tmp = pp_number(m->numbr);
+ tmp = pp_number(m);
else
tmp = pp_string(m->stptr, m->stlen, '"');
str = pp_concat(t1->pp_str, op2str(pc->opcode), tmp);
@@ -522,9 +510,13 @@ cleanup:
break;
case Op_builtin:
+ case Op_ext_builtin:
{
- static char *ext_func = "extension_function()";
- const char *fname = getfname(pc->builtin);
+ const char *fname;
+ if (pc->opcode == Op_builtin)
+ fname = getfname(pc->builtin);
+ else
+ fname = (pc + 1)->func_name;
if (fname != NULL) {
if (pc->expr_count > 0) {
tmp = pp_list(pc->expr_count, "()", ", ");
@@ -534,10 +526,10 @@ cleanup:
str = pp_concat(fname, "()", "");
pp_push(Op_builtin, str, CAN_FREE);
} else
- pp_push(Op_builtin, ext_func, DONT_FREE);
+ fatal(_("internal error: builtin with null fname"));
}
break;
-
+
case Op_K_print:
case Op_K_printf:
case Op_K_print_rec:
@@ -685,8 +677,8 @@ cleanup:
case Op_line_range:
ip = pc + 1;
- pprint(pc->nexti, ip->condpair_left, FALSE);
- pprint(ip->condpair_left->nexti, ip->condpair_right, FALSE);
+ pprint(pc->nexti, ip->condpair_left, false);
+ pprint(ip->condpair_left->nexti, ip->condpair_right, false);
t2 = pp_pop();
t1 = pp_pop();
str = pp_concat(t1->pp_str, ", ", t2->pp_str);
@@ -700,12 +692,12 @@ cleanup:
ip = pc + 1;
indent(ip->while_body->exec_count);
fprintf(prof_fp, "%s (", op2str(pc->opcode));
- pprint(pc->nexti, ip->while_body, FALSE);
+ pprint(pc->nexti, ip->while_body, false);
t1 = pp_pop();
fprintf(prof_fp, "%s) {\n", t1->pp_str);
pp_free(t1);
indent_in();
- pprint(ip->while_body->nexti, pc->target_break, FALSE);
+ pprint(ip->while_body->nexti, pc->target_break, false);
indent_out();
indent(SPACEOVER);
fprintf(prof_fp, "}\n");
@@ -717,9 +709,9 @@ cleanup:
indent(pc->nexti->exec_count);
fprintf(prof_fp, "%s {\n", op2str(pc->opcode));
indent_in();
- pprint(pc->nexti->nexti, ip->doloop_cond, FALSE);
+ pprint(pc->nexti->nexti, ip->doloop_cond, false);
indent_out();
- pprint(ip->doloop_cond, pc->target_break, FALSE);
+ pprint(ip->doloop_cond, pc->target_break, false);
indent(SPACEOVER);
t1 = pp_pop();
fprintf(prof_fp, "} %s (%s)\n", op2str(Op_K_while), t1->pp_str);
@@ -731,23 +723,23 @@ cleanup:
ip = pc + 1;
indent(ip->forloop_body->exec_count);
fprintf(prof_fp, "%s (", op2str(pc->opcode));
- pprint(pc->nexti, ip->forloop_cond, TRUE);
+ pprint(pc->nexti, ip->forloop_cond, true);
fprintf(prof_fp, "; ");
if (ip->forloop_cond->opcode == Op_no_op &&
ip->forloop_cond->nexti == ip->forloop_body)
fprintf(prof_fp, "; ");
else {
- pprint(ip->forloop_cond, ip->forloop_body, TRUE);
+ pprint(ip->forloop_cond, ip->forloop_body, true);
t1 = pp_pop();
fprintf(prof_fp, "%s; ", t1->pp_str);
pp_free(t1);
}
- pprint(pc->target_continue, pc->target_break, TRUE);
+ pprint(pc->target_continue, pc->target_break, true);
fprintf(prof_fp, ") {\n");
indent_in();
- pprint(ip->forloop_body->nexti, pc->target_continue, FALSE);
+ pprint(ip->forloop_body->nexti, pc->target_continue, false);
indent_out();
indent(SPACEOVER);
fprintf(prof_fp, "}\n");
@@ -756,14 +748,15 @@ cleanup:
case Op_K_arrayfor:
{
- char *array, *item;
+ char *array;
+ const char *item;
ip = pc + 1;
t1 = pp_pop();
array = t1->pp_str;
m = ip->forloop_cond->array_var;
if (m->type == Node_param_list)
- item = fparms[m->param_cnt];
+ item = func_params[m->param_cnt].param;
else
item = m->vname;
indent(ip->forloop_body->exec_count);
@@ -771,7 +764,7 @@ cleanup:
item, op2str(Op_in_array), array);
indent_in();
pp_free(t1);
- pprint(ip->forloop_body->nexti, pc->target_break, FALSE);
+ pprint(ip->forloop_body->nexti, pc->target_break, false);
indent_out();
indent(SPACEOVER);
fprintf(prof_fp, "}\n");
@@ -782,11 +775,11 @@ cleanup:
case Op_K_switch:
ip = pc + 1;
fprintf(prof_fp, "%s (", op2str(pc->opcode));
- pprint(pc->nexti, ip->switch_start, FALSE);
+ pprint(pc->nexti, ip->switch_start, false);
t1 = pp_pop();
fprintf(prof_fp, "%s) {\n", t1->pp_str);
pp_free(t1);
- pprint(ip->switch_start, ip->switch_end, FALSE);
+ pprint(ip->switch_start, ip->switch_end, false);
indent(SPACEOVER);
fprintf(prof_fp, "}\n");
pc = pc->target_break;
@@ -802,13 +795,13 @@ cleanup:
} else
fprintf(prof_fp, "%s:\n", op2str(pc->opcode));
indent_in();
- pprint(pc->stmt_start->nexti, pc->stmt_end->nexti, FALSE);
+ pprint(pc->stmt_start->nexti, pc->stmt_end->nexti, false);
indent_out();
break;
case Op_K_if:
fprintf(prof_fp, "%s (", op2str(pc->opcode));
- pprint(pc->nexti, pc->branch_if, FALSE);
+ pprint(pc->nexti, pc->branch_if, false);
t1 = pp_pop();
fprintf(prof_fp, "%s) {", t1->pp_str);
pp_free(t1);
@@ -818,7 +811,7 @@ cleanup:
fprintf(prof_fp, " # %ld", ip->exec_count);
fprintf(prof_fp, "\n");
indent_in();
- pprint(ip->nexti, pc->branch_else, FALSE);
+ pprint(ip->nexti, pc->branch_else, false);
indent_out();
pc = pc->branch_else;
if (pc->nexti->opcode == Op_no_op) {
@@ -830,7 +823,7 @@ cleanup:
case Op_K_else:
fprintf(prof_fp, "} %s {\n", op2str(pc->opcode));
indent_in();
- pprint(pc->nexti, pc->branch_end, FALSE);
+ pprint(pc->nexti, pc->branch_end, false);
indent_out();
indent(SPACEOVER);
fprintf(prof_fp, "}\n");
@@ -842,14 +835,14 @@ cleanup:
NODE *f, *t, *cond;
size_t len;
- pprint(pc->nexti, pc->branch_if, FALSE);
+ pprint(pc->nexti, pc->branch_if, false);
ip = pc->branch_if;
- pprint(ip->nexti, pc->branch_else, FALSE);
+ pprint(ip->nexti, pc->branch_else, false);
ip = pc->branch_else->nexti;
pc = ip->nexti;
assert(pc->opcode == Op_cond_exp);
- pprint(pc->nexti, pc->branch_end, FALSE);
+ pprint(pc->nexti, pc->branch_end, false);
f = pp_pop();
t = pp_pop();
@@ -890,7 +883,7 @@ cleanup:
void
pp_string_fp(Func_print print_func, FILE *fp, const char *in_str,
- size_t len, int delim, int breaklines)
+ size_t len, int delim, bool breaklines)
{
char *s = pp_string(in_str, len, delim);
int count;
@@ -909,7 +902,7 @@ pp_string_fp(Func_print print_func, FILE *fp, const char *in_str,
efree(s);
}
-#ifdef PROFILING
+
/* just_dump --- dump the profile and function stack and keep going */
static RETSIGTYPE
@@ -930,10 +923,9 @@ static RETSIGTYPE
dump_and_exit(int signum)
{
just_dump(signum);
- exit(EXIT_FAILURE);
+ final_exit(EXIT_FAILURE);
}
-#endif
/* dump_prog --- dump the program */
@@ -950,7 +942,7 @@ 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));
- pprint(code, NULL, FALSE);
+ pprint(code, NULL, false);
}
/* prec_level --- return the precedence of an operator, for paren tests */
@@ -1090,10 +1082,10 @@ is_binary(int type)
case Op_in_array:
case Op_K_getline_redir: /* sometimes */
case Op_K_getline:
- return TRUE;
+ return true;
default:
- return FALSE;
+ return false;
}
}
@@ -1211,13 +1203,20 @@ pp_string(const char *in_str, size_t len, int delim)
/* pp_number --- pretty format a number */
char *
-pp_number(AWKNUM d)
+pp_number(NODE *n)
{
#define PP_PRECISION 6
char *str;
emalloc(str, char *, PP_PRECISION + 10, "pp_number");
- sprintf(str, "%0.*g", PP_PRECISION, d);
+#ifdef HAVE_MPFR
+ if (is_mpg_float(n))
+ mpfr_sprintf(str, "%0.*R*g", PP_PRECISION, ROUND_MODE, n->mpg_numbr);
+ else if (is_mpg_integer(n))
+ mpfr_sprintf(str, "%Zd", n->mpg_i);
+ else
+#endif
+ sprintf(str, "%0.*g", PP_PRECISION, n->numbr);
return str;
#undef PP_PRECISION
}
@@ -1228,7 +1227,7 @@ char *
pp_node(NODE *n)
{
if ((n->flags & NUMBER) != 0)
- return pp_number(n->numbr);
+ return pp_number(n);
return pp_string(n->stptr, n->stlen, '"');
}
@@ -1321,31 +1320,29 @@ int
pp_func(INSTRUCTION *pc, void *data ATTRIBUTE_UNUSED)
{
int j;
- char **pnames;
- NODE *f;
- static int first = TRUE;
+ static bool first = true;
+ NODE *func;
int pcount;
if (first) {
- first = FALSE;
+ first = false;
fprintf(prof_fp, _("\n\t# Functions, listed alphabetically\n"));
}
- f = pc->func_body;
+ func = pc->func_body;
fprintf(prof_fp, "\n");
indent(pc->nexti->exec_count);
- fprintf(prof_fp, "%s %s(", op2str(Op_K_function), f->lnode->param);
- pnames = f->parmlist;
- fparms = pnames;
- pcount = f->lnode->param_cnt;
+ fprintf(prof_fp, "%s %s(", op2str(Op_K_function), func->vname);
+ pcount = func->param_cnt;
+ func_params = func->fparms;
for (j = 0; j < pcount; j++) {
- fprintf(prof_fp, "%s", pnames[j]);
+ fprintf(prof_fp, "%s", func_params[j].param);
if (j < pcount - 1)
fprintf(prof_fp, ", ");
}
fprintf(prof_fp, ")\n\t{\n");
indent_in();
- pprint(pc->nexti->nexti, NULL, FALSE); /* function body */
+ pprint(pc->nexti->nexti, NULL, false); /* function body */
indent_out();
fprintf(prof_fp, "\t}\n");
return 0;