| 596 | } |
| 597 | |
| 598 | static void trace_add_env(struct strbuf *dst, const char *const *deltaenv) |
| 599 | { |
| 600 | struct string_list envs = STRING_LIST_INIT_DUP; |
| 601 | const char *const *e; |
| 602 | int i; |
| 603 | int printed_unset = 0; |
| 604 | |
| 605 | /* Last one wins, see run-command.c:prep_childenv() for context */ |
| 606 | for (e = deltaenv; e && *e; e++) { |
| 607 | struct strbuf key = STRBUF_INIT; |
| 608 | const char *equals = strchr(*e, '='); |
| 609 | |
| 610 | if (equals) { |
| 611 | strbuf_add(&key, *e, equals - *e); |
| 612 | string_list_insert(&envs, key.buf)->util = (void *)(equals + 1); |
| 613 | } else { |
| 614 | string_list_insert(&envs, *e)->util = NULL; |
| 615 | } |
| 616 | strbuf_release(&key); |
| 617 | } |
| 618 | |
| 619 | /* "unset X Y...;" */ |
| 620 | for (i = 0; i < envs.nr; i++) { |
| 621 | const char *var = envs.items[i].string; |
| 622 | const char *val = envs.items[i].util; |
| 623 | |
| 624 | if (val || !getenv(var)) |
| 625 | continue; |
| 626 | |
| 627 | if (!printed_unset) { |
| 628 | strbuf_addstr(dst, " unset"); |
| 629 | printed_unset = 1; |
| 630 | } |
| 631 | strbuf_addf(dst, " %s", var); |
| 632 | } |
| 633 | if (printed_unset) |
| 634 | strbuf_addch(dst, ';'); |
| 635 | |
| 636 | /* ... followed by "A=B C=D ..." */ |
| 637 | for (i = 0; i < envs.nr; i++) { |
| 638 | const char *var = envs.items[i].string; |
| 639 | const char *val = envs.items[i].util; |
| 640 | const char *oldval; |
| 641 | |
| 642 | if (!val) |
| 643 | continue; |
| 644 | |
| 645 | oldval = getenv(var); |
| 646 | if (oldval && !strcmp(val, oldval)) |
| 647 | continue; |
| 648 | |
| 649 | strbuf_addf(dst, " %s=", var); |
| 650 | sq_quote_buf_pretty(dst, val); |
| 651 | } |
| 652 | string_list_clear(&envs, 0); |
| 653 | } |
| 654 | |
| 655 | static void trace_run_command(const struct child_process *cp) |
no test coverage detected