X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=config.c;h=8064cae18290d66ee69f1a56e501391ecb317b3d;hb=7d22708b254d4ec28cd865dc5489d175ee6d65c2;hp=80db92990aa9e51fe5eccac6e734b5570c51a12f;hpb=c477553b2f4f621216b25800e121af52e0750087;p=git.git diff --git a/config.c b/config.c index 80db92990..8064cae18 100644 --- a/config.c +++ b/config.c @@ -13,6 +13,7 @@ static FILE *config_file; static const char *config_file_name; static int config_linenr; +static int config_file_eof; static int zlib_compression_seen; static int get_next_char(void) @@ -34,7 +35,7 @@ static int get_next_char(void) if (c == '\n') config_linenr++; if (c == EOF) { - config_file = NULL; + config_file_eof = 1; c = '\n'; } } @@ -118,7 +119,7 @@ static int get_value(config_fn_t fn, char *name, unsigned int len) /* Get the full name */ for (;;) { c = get_next_char(); - if (c == EOF) + if (config_file_eof) break; if (!iskeychar(c)) break; @@ -182,7 +183,7 @@ static int get_base_var(char *name) for (;;) { int c = get_next_char(); - if (c == EOF) + if (config_file_eof) return -1; if (c == ']') return baselen; @@ -205,8 +206,7 @@ static int git_parse_file(config_fn_t fn) for (;;) { int c = get_next_char(); if (c == '\n') { - /* EOF? */ - if (!config_file) + if (config_file_eof) return 0; comment = 0; continue; @@ -309,6 +309,14 @@ int git_config_bool(const char *name, const char *value) return git_config_int(name, value) != 0; } +int git_config_string(const char **dest, const char *var, const char *value) +{ + if (!value) + return config_error_nonbool(var); + *dest = xstrdup(value); + return 0; +} + int git_default_config(const char *var, const char *value) { /* This needs a better name */ @@ -407,50 +415,52 @@ int git_default_config(const char *var, const char *value) return 0; } + if (!strcmp(var, "core.safecrlf")) { + if (value && !strcasecmp(value, "warn")) { + safe_crlf = SAFE_CRLF_WARN; + return 0; + } + safe_crlf = git_config_bool(var, value); + return 0; + } + if (!strcmp(var, "user.name")) { + if (!value) + return config_error_nonbool(var); strlcpy(git_default_name, value, sizeof(git_default_name)); return 0; } if (!strcmp(var, "user.email")) { + if (!value) + return config_error_nonbool(var); strlcpy(git_default_email, value, sizeof(git_default_email)); return 0; } - if (!strcmp(var, "i18n.commitencoding")) { - git_commit_encoding = xstrdup(value); - return 0; - } - - if (!strcmp(var, "i18n.logoutputencoding")) { - git_log_output_encoding = xstrdup(value); - return 0; - } + if (!strcmp(var, "i18n.commitencoding")) + return git_config_string(&git_commit_encoding, var, value); + if (!strcmp(var, "i18n.logoutputencoding")) + return git_config_string(&git_log_output_encoding, var, value); if (!strcmp(var, "pager.color") || !strcmp(var, "color.pager")) { pager_use_color = git_config_bool(var,value); return 0; } - if (!strcmp(var, "core.pager")) { - pager_program = xstrdup(value); - return 0; - } + if (!strcmp(var, "core.pager")) + return git_config_string(&pager_program, var, value); - if (!strcmp(var, "core.editor")) { - editor_program = xstrdup(value); - return 0; - } + if (!strcmp(var, "core.editor")) + return git_config_string(&editor_program, var, value); - if (!strcmp(var, "core.excludesfile")) { - if (!value) - die("core.excludesfile without value"); - excludes_file = xstrdup(value); - return 0; - } + if (!strcmp(var, "core.excludesfile")) + return git_config_string(&excludes_file, var, value); if (!strcmp(var, "core.whitespace")) { + if (!value) + return config_error_nonbool(var); whitespace_rule_cfg = parse_whitespace_rule(value); return 0; } @@ -469,6 +479,7 @@ int git_config_from_file(config_fn_t fn, const char *filename) config_file = f; config_file_name = filename; config_linenr = 1; + config_file_eof = 0; ret = git_parse_file(fn); fclose(f); config_file_name = NULL; @@ -483,14 +494,30 @@ const char *git_etc_gitconfig(void) system_wide = ETC_GITCONFIG; if (!is_absolute_path(system_wide)) { /* interpret path relative to exec-dir */ - const char *exec_path = git_exec_path(); - system_wide = prefix_path(exec_path, strlen(exec_path), - system_wide); + struct strbuf d = STRBUF_INIT; + strbuf_addf(&d, "%s/%s", git_exec_path(), system_wide); + system_wide = strbuf_detach(&d, NULL); } } return system_wide; } +int git_env_bool(const char *k, int def) +{ + const char *v = getenv(k); + return v ? git_config_bool(k, v) : def; +} + +int git_config_system(void) +{ + return !git_env_bool("GIT_CONFIG_NOSYSTEM", 0); +} + +int git_config_global(void) +{ + return !git_env_bool("GIT_CONFIG_NOGLOBAL", 0); +} + int git_config(config_fn_t fn) { int ret = 0; @@ -503,7 +530,7 @@ int git_config(config_fn_t fn) * config file otherwise. */ filename = getenv(CONFIG_ENVIRONMENT); if (!filename) { - if (!access(git_etc_gitconfig(), R_OK)) + if (git_config_system() && !access(git_etc_gitconfig(), R_OK)) ret += git_config_from_file(fn, git_etc_gitconfig()); home = getenv("HOME"); filename = getenv(CONFIG_LOCAL_ENVIRONMENT); @@ -511,7 +538,7 @@ int git_config(config_fn_t fn) filename = repo_config = xstrdup(git_path("config")); } - if (home) { + if (git_config_global() && home) { char *user_config = xstrdup(mkpath("%s/.gitconfig", home)); if (!access(user_config, R_OK)) ret = git_config_from_file(fn, user_config); @@ -700,12 +727,17 @@ static ssize_t find_beginning_of_line(const char* contents, size_t size, size_t equal_offset = size, bracket_offset = size; ssize_t offset; +contline: for (offset = offset_-2; offset > 0 && contents[offset] != '\n'; offset--) switch (contents[offset]) { case '=': equal_offset = offset; break; case ']': bracket_offset = offset; break; } + if (offset > 0 && contents[offset-1] == '\\') { + offset_ = offset; + goto contline; + } if (bracket_offset < equal_offset) { *found_bracket = 1; offset = bracket_offset+1; @@ -918,6 +950,9 @@ int git_config_set_multivar(const char* key, const char* value, contents, contents_sz, store.offset[i]-2, &new_line); + if (copy_end > 0 && contents[copy_end-1] != '\n') + new_line = 1; + /* write the first part of the config */ if (copy_end > copy_begin) { if (write_in_full(fd, contents + copy_begin, @@ -951,14 +986,12 @@ int git_config_set_multivar(const char* key, const char* value, munmap(contents, contents_sz); } - if (close(fd) || commit_lock_file(lock) < 0) { + if (commit_lock_file(lock) < 0) { fprintf(stderr, "Cannot commit config file!\n"); ret = 4; goto out_free; } - /* fd is closed, so don't try to close it below. */ - fd = -1; /* * lock is committed, so don't try to roll it back below. * NOTE: Since lockfile.c keeps a linked list of all created @@ -969,8 +1002,6 @@ int git_config_set_multivar(const char* key, const char* value, ret = 0; out_free: - if (0 <= fd) - close(fd); if (lock) rollback_lock_file(lock); free(config_filename); @@ -1068,9 +1099,18 @@ int git_config_rename_section(const char *old_name, const char *new_name) } fclose(config_file); unlock_and_out: - if (close(out_fd) || commit_lock_file(lock) < 0) + if (commit_lock_file(lock) < 0) ret = error("Cannot commit config file!"); out: free(config_filename); return ret; } + +/* + * Call this to report error for your variable that should not + * get a boolean value (i.e. "[my] var" means "true"). + */ +int config_error_nonbool(const char *var) +{ + return error("Missing value for '%s'", var); +}