Skip to content

Commit 28c2cc3

Browse files
committed
config_file: move reader into config_read only
Right now, we have multiple call sites which initialize a `reader` structure. As the structure is only actually used inside of `config_read`, we can instead just move the reader inside of the `config_read` function. Instead, we can just pass in the configuration file into `config_read`, which eases code readability.
1 parent 83bcd3a commit 28c2cc3

File tree

2 files changed

+44
-45
lines changed

2 files changed

+44
-45
lines changed

src/config_file.c

Lines changed: 31 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ typedef struct {
118118
diskfile_backend *snapshot_from;
119119
} diskfile_readonly_backend;
120120

121-
static int config_read(git_strmap *values, struct reader *reader, git_config_level_t level, int depth);
121+
static int config_read(git_strmap *values, struct config_file *file, git_config_level_t level, int depth);
122122
static int config_write(diskfile_backend *cfg, const char *key, const regex_t *preg, const char *value);
123123
static char *escape_value(const char *ptr);
124124

@@ -264,13 +264,6 @@ static int refcounted_strmap_alloc(refcounted_strmap **out)
264264
return error;
265265
}
266266

267-
static void reader_init(struct reader *reader, struct config_file *file)
268-
{
269-
memset(reader, 0, sizeof(*reader));
270-
git_buf_init(&reader->buffer, 0);
271-
reader->file = file;
272-
}
273-
274267
static void config_file_clear(struct config_file *file)
275268
{
276269
struct config_file *include;
@@ -290,30 +283,22 @@ static void config_file_clear(struct config_file *file)
290283
static int config_open(git_config_backend *cfg, git_config_level_t level)
291284
{
292285
int res;
293-
struct reader reader;
294286
diskfile_backend *b = (diskfile_backend *)cfg;
295287

296288
b->level = level;
297289

298290
if ((res = refcounted_strmap_alloc(&b->header.values)) < 0)
299291
return res;
300292

301-
reader_init(&reader, &b->file);
302-
303-
res = git_futils_readbuffer_updated(
304-
&reader.buffer, b->file.path, &b->file.checksum, NULL);
305-
306293
/* It's fine if the file doesn't exist */
307-
if (res == GIT_ENOTFOUND)
294+
if (!git_path_exists(b->file.path))
308295
return 0;
309296

310-
if (res < 0 || (res = config_read(b->header.values->values, &reader, level, 0)) < 0) {
297+
if (res < 0 || (res = config_read(b->header.values->values, &b->file, level, 0)) < 0) {
311298
refcounted_strmap_free(b->header.values);
312299
b->header.values = NULL;
313300
}
314301

315-
git_buf_free(&reader.buffer);
316-
317302
return res;
318303
}
319304

@@ -354,7 +339,6 @@ static int config_refresh(git_config_backend *cfg)
354339
diskfile_backend *b = (diskfile_backend *)cfg;
355340
refcounted_strmap *values = NULL, *tmp;
356341
struct config_file *include;
357-
struct reader reader;
358342
int error, modified;
359343
uint32_t i;
360344

@@ -365,11 +349,6 @@ static int config_refresh(git_config_backend *cfg)
365349
if (!modified)
366350
return 0;
367351

368-
reader_init(&reader, &b->file);
369-
370-
error = git_futils_readbuffer_updated(
371-
&reader.buffer, b->file.path, &b->file.checksum, NULL);
372-
373352
if ((error = refcounted_strmap_alloc(&values)) < 0)
374353
goto out;
375354

@@ -379,7 +358,7 @@ static int config_refresh(git_config_backend *cfg)
379358
}
380359
git_array_clear(b->file.includes);
381360

382-
if ((error = config_read(values->values, &reader, b->level, 0)) < 0)
361+
if ((error = config_read(values->values, &b->file, b->level, 0)) < 0)
383362
goto out;
384363

385364
if ((error = git_mutex_lock(&b->header.values_mutex)) < 0) {
@@ -395,7 +374,6 @@ static int config_refresh(git_config_backend *cfg)
395374

396375
out:
397376
refcounted_strmap_free(values);
398-
git_buf_free(&reader.buffer);
399377

400378
return (error == GIT_ENOTFOUND) ? 0 : error;
401379
}
@@ -1627,7 +1605,6 @@ static int read_on_variable(
16271605
/* Add or append the new config option */
16281606
if (!git__strcmp(var->entry->name, "include.path")) {
16291607
struct config_file *include;
1630-
struct reader r;
16311608
git_buf path = GIT_BUF_INIT;
16321609
char *dir;
16331610

@@ -1646,48 +1623,55 @@ static int read_on_variable(
16461623
git_array_init(include->includes);
16471624
include->path = git_buf_detach(&path);
16481625

1649-
git_buf_init(&r.buffer, 0);
1650-
memset(&r, 0, sizeof(r));
1651-
r.file = include;
1652-
1653-
result = git_futils_readbuffer_updated(
1654-
&r.buffer, include->path, &include->checksum, NULL);
1626+
result = config_read(parse_data->values, include, parse_data->level, parse_data->depth+1);
16551627

1656-
if (result == 0) {
1657-
result = config_read(parse_data->values, &r, parse_data->level, parse_data->depth+1);
1658-
} else if (result == GIT_ENOTFOUND) {
1628+
if (result == GIT_ENOTFOUND) {
16591629
giterr_clear();
16601630
result = 0;
16611631
}
1662-
1663-
git_buf_free(&r.buffer);
16641632
}
16651633

16661634
return result;
16671635
}
16681636

1669-
static int config_read(git_strmap *values, struct reader *reader, git_config_level_t level, int depth)
1637+
static int config_read(git_strmap *values, struct config_file *file, git_config_level_t level, int depth)
16701638
{
16711639
struct parse_data parse_data;
1640+
struct reader reader;
1641+
int error;
16721642

16731643
if (depth >= MAX_INCLUDE_DEPTH) {
16741644
giterr_set(GITERR_CONFIG, "maximum config include depth reached");
16751645
return -1;
16761646
}
16771647

1648+
git_buf_init(&reader.buffer, 0);
1649+
1650+
if ((error = git_futils_readbuffer(&reader.buffer, file->path)) < 0)
1651+
goto out;
1652+
1653+
if ((error = git_hash_buf(&file->checksum, reader.buffer.ptr, reader.buffer.size)) < 0)
1654+
goto out;
1655+
16781656
/* Initialize the reading position */
1679-
reader->read_ptr = reader->buffer.ptr;
1680-
reader->eof = 0;
1657+
reader.file = file;
1658+
reader.line_number = 0;
1659+
reader.read_ptr = reader.buffer.ptr;
1660+
reader.eof = 0;
16811661

16821662
/* If the file is empty, there's nothing for us to do */
1683-
if (*reader->read_ptr == '\0')
1684-
return 0;
1663+
if (*reader.read_ptr == '\0')
1664+
goto out;
16851665

16861666
parse_data.values = values;
16871667
parse_data.level = level;
16881668
parse_data.depth = depth;
16891669

1690-
return config_parse(reader, NULL, read_on_variable, NULL, NULL, &parse_data);
1670+
error = config_parse(&reader, NULL, read_on_variable, NULL, NULL, &parse_data);
1671+
1672+
out:
1673+
git_buf_free(&reader.buffer);
1674+
return error;
16911675
}
16921676

16931677
static int write_section(git_buf *fbuf, const char *key)
@@ -1923,7 +1907,9 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p
19231907
struct reader reader;
19241908
struct write_data write_data;
19251909

1926-
reader_init(&reader, &cfg->file);
1910+
memset(&reader, 0, sizeof(reader));
1911+
git_buf_init(&reader.buffer, 0);
1912+
reader.file = &cfg->file;
19271913

19281914
if (cfg->locked) {
19291915
result = git_buf_puts(&reader.buffer, git_buf_cstr(&cfg->locked_content));

tests/config/include.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,16 @@ void test_config_include__removing_include_removes_values(void)
133133
cl_git_mkfile("top-level", "");
134134
cl_git_fail(git_config_get_string_buf(&buf, cfg, "foo.bar"));
135135
}
136+
137+
void test_config_include__rewriting_include_refreshes_values(void)
138+
{
139+
cl_git_mkfile("top-level", "[include]\npath = first\n[include]\npath = second");
140+
cl_git_mkfile("first", "[first]\nfoo = bar");
141+
cl_git_mkfile("second", "[second]\nfoo = bar");
142+
143+
cl_git_pass(git_config_open_ondisk(&cfg, "top-level"));
144+
cl_git_mkfile("first", "[first]\nother = value");
145+
cl_git_fail(git_config_get_string_buf(&buf, cfg, "foo.bar"));
146+
cl_git_pass(git_config_get_string_buf(&buf, cfg, "first.other"));
147+
cl_assert_equal_s(buf.ptr, "value");
148+
}

0 commit comments

Comments
 (0)