From b7830887ea34488b339c18ad89b49af085f4635a Mon Sep 17 00:00:00 2001 From: Joel Rosdahl Date: Tue, 19 Jul 2011 12:44:20 +0200 Subject: [PATCH] config: Implement conf_set_value_in_file() --- conf.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ conf.h | 2 ++ test/test_conf.c | 24 ++++++++++++++++++++++ 3 files changed, 78 insertions(+) diff --git a/conf.c b/conf.c index cd0b7c52c..383b1a803 100644 --- a/conf.c +++ b/conf.c @@ -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; +} diff --git a/conf.h b/conf.h index 0890b42bd..257faa966 100644 --- a/conf.h +++ b/conf.h @@ -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 diff --git a/test/test_conf.c b/test/test_conf.c index 548584831..4b6c09f87 100644 --- a/test/test_conf.c +++ b/test/test_conf.c @@ -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 -- 2.47.3