diff options
Diffstat (limited to 'profile.c')
-rw-r--r-- | profile.c | 108 |
1 files changed, 95 insertions, 13 deletions
@@ -240,7 +240,7 @@ pprint(INSTRUCTION *startp, INSTRUCTION *endp, int flags) /* 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) + && pc->nexti->memory->comment_type == BLOCK_COMMENT) print_comment(pc->nexti, -1); ip1 = (pc + 1)->firsti; ip2 = (pc + 1)->lasti; @@ -624,7 +624,8 @@ cleanup: case Op_K_printf: case Op_K_print_rec: if (pc->opcode == Op_K_print_rec) - tmp = pp_group3(" ", op2str(Op_field_spec), "0"); + // instead of `print $0', just `print' + tmp = strdup(""); else if (pc->redir_type != 0) tmp = pp_list(pc->expr_count, "()", ", "); else { @@ -901,10 +902,14 @@ cleanup: pprint(pc->nexti, ip1->switch_start, NO_PPRINT_FLAGS); t1 = pp_pop(); fprintf(prof_fp, "%s) {\n", t1->pp_str); + if (pc->comment) + print_comment(pc->comment, 0); pp_free(t1); pprint(ip1->switch_start, ip1->switch_end, NO_PPRINT_FLAGS); indent(SPACEOVER); fprintf(prof_fp, "}\n"); + if (ip1->switch_end->comment) + print_comment(ip1->switch_end->comment, 0); pc = pc->target_break; break; @@ -937,6 +942,8 @@ cleanup: fprintf(prof_fp, " # %ld", ip1->exec_count); ip1 = end_line(ip1); indent_in(); + if (pc->comment != NULL) + print_comment(pc->comment, indent_level); pprint(ip1->nexti, pc->branch_else, NO_PPRINT_FLAGS); indent_out(); pc = pc->branch_else; @@ -944,7 +951,7 @@ cleanup: indent(SPACEOVER); fprintf(prof_fp, "}"); if (pc->nexti->nexti->opcode != Op_comment - || pc->nexti->nexti->memory->comment_type == FULL_COMMENT) + || pc->nexti->nexti->memory->comment_type == BLOCK_COMMENT) fprintf(prof_fp, "\n"); /* else It will be printed at the top. */ @@ -980,6 +987,8 @@ cleanup: end_line(pc); skip_comment = true; indent_in(); + if (pc->comment != NULL) + print_comment(pc->comment, indent_level); pprint(pc->nexti, pc->branch_end, NO_PPRINT_FLAGS); indent_out(); indent(SPACEOVER); @@ -999,6 +1008,11 @@ cleanup: { NODE *f, *t, *cond; size_t len; + INSTRUCTION *qm_comment = NULL, *colon_comment = NULL; + static const char tabs[] = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; + static const size_t tabs_len = sizeof(tabs) - 1; + + qm_comment = pc->comment; pprint(pc->nexti, pc->branch_if, NO_PPRINT_FLAGS); ip1 = pc->branch_if; @@ -1006,6 +1020,7 @@ cleanup: ip1 = pc->branch_else->nexti; pc = ip1->nexti; + colon_comment = pc->comment; assert(pc->opcode == Op_cond_exp); pprint(pc->nexti, pc->branch_end, NO_PPRINT_FLAGS); @@ -1013,9 +1028,73 @@ cleanup: t = pp_pop(); cond = pp_pop(); - len = f->pp_len + t->pp_len + cond->pp_len + 12; - emalloc(str, char *, len, "pprint"); - sprintf(str, "%s ? %s : %s", cond->pp_str, t->pp_str, f->pp_str); + if (indent_level + 1 > tabs_len) + // We're allowed to be snarky, occasionally. + fatal(_("Program indentation level too deep. Consider refactoring your code")); + + /* + * This stuff handles comments that come after a ?, :, or both. + * Allowing newlines after ? and : is a gawk extension. + * Theoretically this is fragile, since ?: expressions can be nested. + * In practice, it's not, since if there was a comment following ? or : + * in the original code, then it wasn't nested. + */ + + len = f->pp_len + t->pp_len + cond->pp_len + 12; + if (qm_comment == NULL && colon_comment == NULL) { + // easy case + emalloc(str, char *, len, "pprint"); + sprintf(str, "%s ? %s : %s", cond->pp_str, t->pp_str, f->pp_str); + } else if (qm_comment != NULL && colon_comment != NULL) { + len += qm_comment->memory->stlen + // comments + colon_comment->memory->stlen + + 2 * (indent_level + 1) + 3 + // indentation + t->pp_len + 6; + emalloc(str, char *, len, "pprint"); + sprintf(str, + "%s ? %s" // cond ? comment + "%.*s %s" // indent true-part + " : %s" // : comment + "%.*s %s", // indent false-part + cond->pp_str, // condition + qm_comment->memory->stptr, // comment + (int) indent_level + 1, tabs, // indent + t->pp_str, // true part + colon_comment->memory->stptr, // comment + (int) indent_level + 1, tabs, // indent + f->pp_str // false part + ); + } else if (qm_comment != NULL) { + len += qm_comment->memory->stlen + // comment + 1 * (indent_level + 1) + 3 + // indentation + t->pp_len + 3; + emalloc(str, char *, len, "pprint"); + sprintf(str, + "%s ? %s" // cond ? comment + "%.*s %s" // indent true-part + " : %s", // : false-part + cond->pp_str, // condition + qm_comment->memory->stptr, // comment + (int) indent_level + 1, tabs, // indent + t->pp_str, // true part + f->pp_str // false part + ); + } else { + len += colon_comment->memory->stlen + // comment + 1 * (indent_level + 1) + 3 + // indentation + t->pp_len + 3; + emalloc(str, char *, len, "pprint"); + sprintf(str, + "%s ? %s" // cond ? true-part + " : %s" // : comment + "%.*s %s", // indent false-part + cond->pp_str, // condition + t->pp_str, // true part + colon_comment->memory->stptr, // comment + (int) indent_level + 1, tabs, // indent + f->pp_str // false part + ); + } pp_free(cond); pp_free(t); @@ -1065,7 +1144,7 @@ end_line(INSTRUCTION *ip) return ret; } -/* pp_string_fp --- printy print a string to the fp */ +/* pp_string_fp --- pretty print a string to the fp */ /* * This routine concentrates string pretty printing in one place, @@ -1158,8 +1237,13 @@ print_comment(INSTRUCTION* pc, long in) after_newline = false; } putc(*text, prof_fp); - if (*text == '\n') - after_newline = true; + after_newline = (*text == '\n'); + } + + if (pc->comment) { + // chaining should only be two deep + assert(pc->comment->comment == NULL); + print_comment(pc->comment, in); } } @@ -1736,10 +1820,8 @@ pp_func(INSTRUCTION *pc, void *data ATTRIBUTE_UNUSED) 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; - } + if (pc->comment != NULL) + print_comment(pc->comment, -1); /* -1 ==> don't indent */ indent(pc->nexti->exec_count); fprintf(prof_fp, "%s %s(", op2str(Op_K_function), func->vname); |