config: Implement conf_set_value_in_file()

This commit is contained in:
Joel Rosdahl 2011-07-19 12:44:20 +02:00
parent 8611023b7a
commit b7830887ea
3 changed files with 78 additions and 0 deletions

52
conf.c
View File

@ -550,3 +550,55 @@ conf_update_from_environment(struct conf *conf, char **errmsg)
return true;
}
bool
conf_set_value_in_file(const char *path, const char *key, const char *value,
char **errmsg)
{
FILE *infile, *outfile;
char *outpath;
char buf[10000];
bool found;
infile = fopen(path, "r");
if (!infile) {
*errmsg = format("%s: %s", path, strerror(errno));
return false;
}
outpath = format("%s.tmp.%s", path, tmp_string());
outfile = fopen(outpath, "w");
if (!outfile) {
*errmsg = format("%s: %s", outpath, strerror(errno));
free(outpath);
fclose(infile);
return false;
}
found = false;
while (fgets(buf, sizeof(buf), infile)) {
char *errmsg2, *key2, *value2;
bool ok;
ok = parse_line(buf, &key2, &value2, &errmsg2);
if (ok && key2 && str_eq(key2, key)) {
found = true;
fprintf(outfile, "%s = %s\n", key, value);
} else {
fputs(buf, outfile);
}
}
if (!found) {
fprintf(outfile, "%s = %s\n", key, value);
}
fclose(infile);
fclose(outfile);
if (x_rename(outpath, path) != 0) {
*errmsg = format("rename %s to %s: %s", outpath, path, strerror(errno));
return false;
}
free(outpath);
return true;
}

2
conf.h
View File

@ -36,5 +36,7 @@ struct conf *conf_create(void);
void conf_free(struct conf *conf);
bool conf_read(struct conf *conf, const char *path, char **errmsg);
bool conf_update_from_environment(struct conf *conf, char **errmsg);
bool conf_set_value_in_file(const char *path, const char *key,
const char *value, char **errmsg);
#endif

View File

@ -302,4 +302,28 @@ TEST(conf_update_from_environment)
conf_free(conf);
}
TEST(conf_set_new_value)
{
char *errmsg;
char *data;
create_file("ccache.conf", "flavour = vanilla\n");
CHECK(conf_set_value_in_file("ccache.conf", "topping", "chocolate", &errmsg));
data = read_text_file("ccache.conf", 0);
CHECK(data);
CHECK_STR_EQ_FREE2("flavour = vanilla\ntopping = chocolate\n", data);
}
TEST(conf_set_existing_value)
{
char *errmsg;
char *data;
create_file("ccache.conf", "flavour = chocolate\ntopping = chocolate\n");
CHECK(conf_set_value_in_file("ccache.conf", "flavour", "vanilla", &errmsg));
data = read_text_file("ccache.conf", 0);
CHECK(data);
CHECK_STR_EQ_FREE2("flavour = vanilla\ntopping = chocolate\n", data);
}
TEST_SUITE_END