diff options
Diffstat (limited to 'profile.c')
-rw-r--r-- | profile.c | 159 |
1 files changed, 78 insertions, 81 deletions
@@ -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; |