|  | #include "cache.h" | 
|  | #include "config.h" | 
|  | #include "dir.h" | 
|  | #include "tr2_sysenv.h" | 
|  |  | 
|  | /* | 
|  | * Each entry represents a trace2 setting. | 
|  | * See Documentation/technical/api-trace2.txt | 
|  | */ | 
|  | struct tr2_sysenv_entry { | 
|  | const char *env_var_name; | 
|  | const char *git_config_name; | 
|  |  | 
|  | char *value; | 
|  | unsigned int getenv_called : 1; | 
|  | }; | 
|  |  | 
|  | /* | 
|  | * This table must match "enum tr2_sysenv_variable" in tr2_sysenv.h. | 
|  | * | 
|  | * The strings in this table are constant and must match the published | 
|  | * config and environment variable names as described in the documentation. | 
|  | * | 
|  | * We do not define entries for the GIT_TRACE2_PARENT_* environment | 
|  | * variables because they are transient and used to pass information | 
|  | * from parent to child git processes, rather than settings. | 
|  | */ | 
|  | /* clang-format off */ | 
|  | static struct tr2_sysenv_entry tr2_sysenv_settings[] = { | 
|  | [TR2_SYSENV_CFG_PARAM]     = { "GIT_TRACE2_CONFIG_PARAMS", | 
|  | "trace2.configparams" }, | 
|  |  | 
|  | [TR2_SYSENV_DST_DEBUG]     = { "GIT_TRACE2_DST_DEBUG", | 
|  | "trace2.destinationdebug" }, | 
|  |  | 
|  | [TR2_SYSENV_NORMAL]        = { "GIT_TRACE2", | 
|  | "trace2.normaltarget" }, | 
|  | [TR2_SYSENV_NORMAL_BRIEF]  = { "GIT_TRACE2_BRIEF", | 
|  | "trace2.normalbrief" }, | 
|  |  | 
|  | [TR2_SYSENV_EVENT]         = { "GIT_TRACE2_EVENT", | 
|  | "trace2.eventtarget" }, | 
|  | [TR2_SYSENV_EVENT_BRIEF]   = { "GIT_TRACE2_EVENT_BRIEF", | 
|  | "trace2.eventbrief" }, | 
|  | [TR2_SYSENV_EVENT_NESTING] = { "GIT_TRACE2_EVENT_NESTING", | 
|  | "trace2.eventnesting" }, | 
|  |  | 
|  | [TR2_SYSENV_PERF]          = { "GIT_TRACE2_PERF", | 
|  | "trace2.perftarget" }, | 
|  | [TR2_SYSENV_PERF_BRIEF]    = { "GIT_TRACE2_PERF_BRIEF", | 
|  | "trace2.perfbrief" }, | 
|  | }; | 
|  | /* clang-format on */ | 
|  |  | 
|  | static int tr2_sysenv_cb(const char *key, const char *value, void *d) | 
|  | { | 
|  | int k; | 
|  |  | 
|  | if (!starts_with(key, "trace2.")) | 
|  | return 0; | 
|  |  | 
|  | for (k = 0; k < ARRAY_SIZE(tr2_sysenv_settings); k++) { | 
|  | if (!strcmp(key, tr2_sysenv_settings[k].git_config_name)) { | 
|  | free(tr2_sysenv_settings[k].value); | 
|  | tr2_sysenv_settings[k].value = xstrdup(value); | 
|  | return 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Load Trace2 settings from the system config (usually "/etc/gitconfig" | 
|  | * unless we were built with a runtime-prefix).  These are intended to | 
|  | * define the default values for Trace2 as requested by the administrator. | 
|  | * | 
|  | * Then override with the Trace2 settings from the global config. | 
|  | */ | 
|  | void tr2_sysenv_load(void) | 
|  | { | 
|  | if (ARRAY_SIZE(tr2_sysenv_settings) != TR2_SYSENV_MUST_BE_LAST) | 
|  | BUG("tr2_sysenv_settings size is wrong"); | 
|  |  | 
|  | read_very_early_config(tr2_sysenv_cb, NULL); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Return the value for the requested Trace2 setting from these sources: | 
|  | * the system config, the global config, and the environment. | 
|  | */ | 
|  | const char *tr2_sysenv_get(enum tr2_sysenv_variable var) | 
|  | { | 
|  | if (var >= TR2_SYSENV_MUST_BE_LAST) | 
|  | BUG("tr2_sysenv_get invalid var '%d'", var); | 
|  |  | 
|  | if (!tr2_sysenv_settings[var].getenv_called) { | 
|  | const char *v = getenv(tr2_sysenv_settings[var].env_var_name); | 
|  | if (v && *v) { | 
|  | free(tr2_sysenv_settings[var].value); | 
|  | tr2_sysenv_settings[var].value = xstrdup(v); | 
|  | } | 
|  | tr2_sysenv_settings[var].getenv_called = 1; | 
|  | } | 
|  |  | 
|  | return tr2_sysenv_settings[var].value; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Return a friendly name for this setting that is suitable for printing | 
|  | * in an error messages. | 
|  | */ | 
|  | const char *tr2_sysenv_display_name(enum tr2_sysenv_variable var) | 
|  | { | 
|  | if (var >= TR2_SYSENV_MUST_BE_LAST) | 
|  | BUG("tr2_sysenv_get invalid var '%d'", var); | 
|  |  | 
|  | return tr2_sysenv_settings[var].env_var_name; | 
|  | } | 
|  |  | 
|  | void tr2_sysenv_release(void) | 
|  | { | 
|  | int k; | 
|  |  | 
|  | for (k = 0; k < ARRAY_SIZE(tr2_sysenv_settings); k++) | 
|  | free(tr2_sysenv_settings[k].value); | 
|  | } |