return isalnum(c) || c == '-';
}
-static int get_value(config_fn_t fn, char *name, unsigned int len)
+static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
{
int c;
char *value;
if (!value)
return -1;
}
- return fn(name, value);
+ return fn(name, value, data);
}
static int get_extended_base_var(char *name, int baselen, int c)
}
}
-static int git_parse_file(config_fn_t fn)
+static int git_parse_file(config_fn_t fn, void *data)
{
int comment = 0;
int baselen = 0;
if (!isalpha(c))
break;
var[baselen] = tolower(c);
- if (get_value(fn, var, baselen+1) < 0)
+ if (get_value(fn, data, var, baselen+1) < 0)
break;
}
die("bad config file line %d in %s", config_linenr, config_file_name);
return 0;
}
-int git_default_config(const char *var, const char *value)
+int git_default_config(const char *var, const char *value, void *dummy)
{
/* This needs a better name */
if (!strcmp(var, "core.filemode")) {
if (!value)
return config_error_nonbool(var);
strlcpy(git_default_name, value, sizeof(git_default_name));
+ if (git_default_email[0])
+ user_ident_explicitly_given = 1;
return 0;
}
if (!value)
return config_error_nonbool(var);
strlcpy(git_default_email, value, sizeof(git_default_email));
+ if (git_default_name[0])
+ user_ident_explicitly_given = 1;
return 0;
}
return 0;
}
-int git_config_from_file(config_fn_t fn, const char *filename)
+int git_config_from_file(config_fn_t fn, const char *filename, void *data)
{
int ret;
FILE *f = fopen(filename, "r");
config_file_name = filename;
config_linenr = 1;
config_file_eof = 0;
- ret = git_parse_file(fn);
+ ret = git_parse_file(fn, data);
fclose(f);
config_file_name = NULL;
}
return system_wide;
}
-int git_env_bool(const char *k, int def)
+static int git_env_bool(const char *k, int def)
{
const char *v = getenv(k);
return v ? git_config_bool(k, v) : def;
return !git_env_bool("GIT_CONFIG_NOGLOBAL", 0);
}
-int git_config(config_fn_t fn)
+int git_config(config_fn_t fn, void *data)
{
int ret = 0;
char *repo_config = NULL;
filename = getenv(CONFIG_ENVIRONMENT);
if (!filename) {
if (git_config_system() && !access(git_etc_gitconfig(), R_OK))
- ret += git_config_from_file(fn, git_etc_gitconfig());
+ ret += git_config_from_file(fn, git_etc_gitconfig(),
+ data);
home = getenv("HOME");
filename = getenv(CONFIG_LOCAL_ENVIRONMENT);
if (!filename)
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);
+ ret = git_config_from_file(fn, user_config, data);
free(user_config);
}
- ret += git_config_from_file(fn, filename);
+ ret += git_config_from_file(fn, filename, data);
free(repo_config);
return ret;
}
!regexec(store.value_regex, value, 0, NULL, 0)));
}
-static int store_aux(const char* key, const char* value)
+static int store_aux(const char* key, const char* value, void *cb)
{
const char *ep;
size_t section_len;
case KEY_SEEN:
if (matches(key, value)) {
if (store.seen == 1 && store.multi_replace == 0) {
- fprintf(stderr,
- "Warning: %s has multiple values\n",
- key);
+ warning("%s has multiple values", key);
} else if (store.seen >= MAX_MATCHES) {
- fprintf(stderr, "Too many matches\n");
+ error("too many matches for %s", key);
return 1;
}
return 0;
}
-static int write_error(void)
+static int write_error(const char *filename)
{
- fprintf(stderr, "Failed to write new configuration file\n");
+ error("failed to write new configuration file %s", filename);
/* Same error code as "failed to rename". */
return 4;
if (dot) {
strbuf_addf(&sb, "[%.*s \"", (int)(dot - key), key);
for (i = dot - key + 1; i < store.baselen; i++) {
- if (key[i] == '"')
+ if (key[i] == '"' || key[i] == '\\')
strbuf_addch(&sb, '\\');
strbuf_addch(&sb, key[i]);
}
*/
if (last_dot == NULL) {
- fprintf(stderr, "key does not contain a section: %s\n", key);
+ error("key does not contain a section: %s", key);
ret = 2;
goto out_free;
}
/* Leave the extended basename untouched.. */
if (!dot || i > store.baselen) {
if (!iskeychar(c) || (i == store.baselen+1 && !isalpha(c))) {
- fprintf(stderr, "invalid key: %s\n", key);
+ error("invalid key: %s", key);
free(store.key);
ret = 1;
goto out_free;
}
c = tolower(c);
} else if (c == '\n') {
- fprintf(stderr, "invalid key (newline): %s\n", key);
+ error("invalid key (newline): %s", key);
free(store.key);
ret = 1;
goto out_free;
lock = xcalloc(sizeof(struct lock_file), 1);
fd = hold_lock_file_for_update(lock, config_filename, 0);
if (fd < 0) {
- fprintf(stderr, "could not lock config file\n");
+ error("could not lock config file %s", config_filename);
free(store.key);
ret = -1;
goto out_free;
store.value_regex = (regex_t*)xmalloc(sizeof(regex_t));
if (regcomp(store.value_regex, value_regex,
REG_EXTENDED)) {
- fprintf(stderr, "Invalid pattern: %s\n",
- value_regex);
+ error("invalid pattern: %s", value_regex);
free(store.value_regex);
ret = 6;
goto out_free;
* As a side effect, we make sure to transform only a valid
* existing config file.
*/
- if (git_config_from_file(store_aux, config_filename)) {
- fprintf(stderr, "invalid config file\n");
+ if (git_config_from_file(store_aux, config_filename, NULL)) {
+ error("invalid config file %s", config_filename);
free(store.key);
if (store.value_regex != NULL) {
regfree(store.value_regex);
}
if (commit_lock_file(lock) < 0) {
- fprintf(stderr, "Cannot commit config file!\n");
+ error("could not commit config file %s", config_filename);
ret = 4;
goto out_free;
}
return ret;
write_err_out:
- ret = write_error();
+ ret = write_error(lock->filename);
goto out_free;
}
config_filename = xstrdup(config_filename);
out_fd = hold_lock_file_for_update(lock, config_filename, 0);
if (out_fd < 0) {
- ret = error("Could not lock config file!");
+ ret = error("could not lock config file %s", config_filename);
goto out;
}
}
store.baselen = strlen(new_name);
if (!store_write_section(out_fd, new_name)) {
- ret = write_error();
+ ret = write_error(lock->filename);
goto out;
}
continue;
continue;
length = strlen(buf);
if (write_in_full(out_fd, buf, length) != length) {
- ret = write_error();
+ ret = write_error(lock->filename);
goto out;
}
}
fclose(config_file);
unlock_and_out:
if (commit_lock_file(lock) < 0)
- ret = error("Cannot commit config file!");
+ ret = error("could not commit config file %s", config_filename);
out:
free(config_filename);
return ret;