Skip to content

Commit a6ad9e8

Browse files
authored
Merge pull request libgit2#5134 from pks-t/pks/config-parser-separation
Config parser separation
2 parents ba9725a + dbeadf8 commit a6ad9e8

File tree

5 files changed

+98
-96
lines changed

5 files changed

+98
-96
lines changed

src/config_file.c

Lines changed: 56 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@
2626
/* Max depth for [include] directives */
2727
#define MAX_INCLUDE_DEPTH 10
2828

29+
typedef struct diskfile {
30+
git_futils_filestamp stamp;
31+
git_oid checksum;
32+
char *path;
33+
git_array_t(struct diskfile) includes;
34+
} diskfile;
35+
2936
typedef struct {
3037
git_config_backend parent;
3138
/* mutex to coordinate accessing the values */
@@ -44,7 +51,7 @@ typedef struct {
4451
git_filebuf locked_buf;
4552
git_buf locked_content;
4653

47-
git_config_file file;
54+
diskfile file;
4855
} diskfile_backend;
4956

5057
typedef struct {
@@ -55,14 +62,14 @@ typedef struct {
5562

5663
typedef struct {
5764
const git_repository *repo;
58-
const char *file_path;
65+
diskfile *file;
5966
git_config_entries *entries;
6067
git_config_level_t level;
6168
unsigned int depth;
6269
} diskfile_parse_state;
6370

64-
static int config_read(git_config_entries *entries, const git_repository *repo, git_config_file *file, git_config_level_t level, int depth);
65-
static int config_read_buffer(git_config_entries *entries, const git_repository *repo, git_config_file *file, git_config_level_t level, int depth, const char *buf, size_t buflen);
71+
static int config_read(git_config_entries *entries, const git_repository *repo, diskfile *file, git_config_level_t level, int depth);
72+
static int config_read_buffer(git_config_entries *entries, const git_repository *repo, diskfile *file, git_config_level_t level, int depth, const char *buf, size_t buflen);
6673
static int config_write(diskfile_backend *cfg, const char *orig_key, const char *key, const p_regex_t *preg, const char *value);
6774
static char *escape_value(const char *ptr);
6875

@@ -96,9 +103,9 @@ static git_config_entries *diskfile_entries_take(diskfile_header *h)
96103
return entries;
97104
}
98105

99-
static void config_file_clear(git_config_file *file)
106+
static void config_file_clear(diskfile *file)
100107
{
101-
git_config_file *include;
108+
diskfile *include;
102109
uint32_t i;
103110

104111
if (file == NULL)
@@ -134,9 +141,9 @@ static int config_open(git_config_backend *cfg, git_config_level_t level, const
134141
return res;
135142
}
136143

137-
static int config_is_modified(int *modified, git_config_file *file)
144+
static int config_is_modified(int *modified, diskfile *file)
138145
{
139-
git_config_file *include;
146+
diskfile *include;
140147
git_buf buf = GIT_BUF_INIT;
141148
git_oid hash;
142149
uint32_t i;
@@ -174,9 +181,9 @@ static int config_set_entries(git_config_backend *cfg, git_config_entries *entri
174181
{
175182
diskfile_backend *b = (diskfile_backend *)cfg;
176183
git_config_entries *old = NULL;
177-
git_config_file *include;
184+
diskfile *include;
178185
int error;
179-
size_t i;
186+
uint32_t i;
180187

181188
if (b->header.parent.readonly)
182189
return config_error_readonly();
@@ -677,18 +684,17 @@ static char *escape_value(const char *ptr)
677684
return git_buf_detach(&buf);
678685
}
679686

680-
static int parse_include(git_config_parser *reader,
681-
diskfile_parse_state *parse_data, const char *file)
687+
static int parse_include(diskfile_parse_state *parse_data, const char *file)
682688
{
683-
git_config_file *include;
689+
diskfile *include;
684690
git_buf path = GIT_BUF_INIT;
685691
char *dir;
686692
int result;
687693

688694
if (!file)
689695
return 0;
690696

691-
if ((result = git_path_dirname_r(&path, reader->file->path)) < 0)
697+
if ((result = git_path_dirname_r(&path, parse_data->file->path)) < 0)
692698
return result;
693699

694700
dir = git_buf_detach(&path);
@@ -698,7 +704,7 @@ static int parse_include(git_config_parser *reader,
698704
if (result < 0)
699705
return result;
700706

701-
include = git_array_alloc(reader->file->includes);
707+
include = git_array_alloc(parse_data->file->includes);
702708
GIT_ERROR_CHECK_ALLOC(include);
703709
memset(include, 0, sizeof(*include));
704710
git_array_init(include->includes);
@@ -783,8 +789,7 @@ static const struct {
783789
{ "gitdir/i:", conditional_match_gitdir_i }
784790
};
785791

786-
static int parse_conditional_include(git_config_parser *reader,
787-
diskfile_parse_state *parse_data, const char *section, const char *file)
792+
static int parse_conditional_include(diskfile_parse_state *parse_data, const char *section, const char *file)
788793
{
789794
char *condition;
790795
size_t i;
@@ -802,12 +807,12 @@ static int parse_conditional_include(git_config_parser *reader,
802807

803808
if ((error = conditions[i].matches(&matches,
804809
parse_data->repo,
805-
parse_data->file_path,
810+
parse_data->file->path,
806811
condition + strlen(conditions[i].prefix))) < 0)
807812
break;
808813

809814
if (matches)
810-
error = parse_include(reader, parse_data, file);
815+
error = parse_include(parse_data, file);
811816

812817
break;
813818
}
@@ -831,6 +836,7 @@ static int read_on_variable(
831836
const char *c;
832837
int result = 0;
833838

839+
GIT_UNUSED(reader);
834840
GIT_UNUSED(line);
835841
GIT_UNUSED(line_len);
836842

@@ -863,19 +869,18 @@ static int read_on_variable(
863869

864870
/* Add or append the new config option */
865871
if (!git__strcmp(entry->name, "include.path"))
866-
result = parse_include(reader, parse_data, entry->value);
872+
result = parse_include(parse_data, entry->value);
867873
else if (!git__prefixcmp(entry->name, "includeif.") &&
868874
!git__suffixcmp(entry->name, ".path"))
869-
result = parse_conditional_include(reader, parse_data,
870-
entry->name, entry->value);
875+
result = parse_conditional_include(parse_data, entry->name, entry->value);
871876

872877
return result;
873878
}
874879

875880
static int config_read_buffer(
876881
git_config_entries *entries,
877882
const git_repository *repo,
878-
git_config_file *file,
883+
diskfile *file,
879884
git_config_level_t level,
880885
int depth,
881886
const char *buf,
@@ -891,7 +896,7 @@ static int config_read_buffer(
891896
}
892897

893898
/* Initialize the reading position */
894-
reader.file = file;
899+
reader.path = file->path;
895900
git_parse_ctx_init(&reader.ctx, buf, buflen);
896901

897902
/* If the file is empty, there's nothing for us to do */
@@ -901,7 +906,7 @@ static int config_read_buffer(
901906
}
902907

903908
parse_data.repo = repo;
904-
parse_data.file_path = file->path;
909+
parse_data.file = file;
905910
parse_data.entries = entries;
906911
parse_data.level = level;
907912
parse_data.depth = depth;
@@ -915,7 +920,7 @@ static int config_read_buffer(
915920
static int config_read(
916921
git_config_entries *entries,
917922
const git_repository *repo,
918-
git_config_file *file,
923+
diskfile *file,
919924
git_config_level_t level,
920925
int depth)
921926
{
@@ -1169,37 +1174,30 @@ static int write_on_eof(
11691174
*/
11701175
static int config_write(diskfile_backend *cfg, const char *orig_key, const char *key, const p_regex_t *preg, const char* value)
11711176
{
1172-
int result;
1173-
char *orig_section, *section, *orig_name, *name, *ldot;
1174-
git_filebuf file = GIT_FILEBUF_INIT;
1177+
char *orig_section = NULL, *section = NULL, *orig_name, *name, *ldot;
11751178
git_buf buf = GIT_BUF_INIT, contents = GIT_BUF_INIT;
1176-
git_config_parser reader;
1179+
git_config_parser parser = GIT_CONFIG_PARSER_INIT;
1180+
git_filebuf file = GIT_FILEBUF_INIT;
11771181
struct write_data write_data;
1182+
int error;
11781183

1179-
memset(&reader, 0, sizeof(reader));
1180-
reader.file = &cfg->file;
1184+
memset(&write_data, 0, sizeof(write_data));
11811185

11821186
if (cfg->locked) {
1183-
result = git_buf_puts(&contents, git_buf_cstr(&cfg->locked_content) == NULL ? "" : git_buf_cstr(&cfg->locked_content));
1187+
error = git_buf_puts(&contents, git_buf_cstr(&cfg->locked_content) == NULL ? "" : git_buf_cstr(&cfg->locked_content));
11841188
} else {
1185-
/* Lock the file */
1186-
if ((result = git_filebuf_open(
1187-
&file, cfg->file.path, GIT_FILEBUF_HASH_CONTENTS, GIT_CONFIG_FILE_MODE)) < 0) {
1188-
git_buf_dispose(&contents);
1189-
return result;
1190-
}
1189+
if ((error = git_filebuf_open(&file, cfg->file.path, GIT_FILEBUF_HASH_CONTENTS,
1190+
GIT_CONFIG_FILE_MODE)) < 0)
1191+
goto done;
11911192

11921193
/* We need to read in our own config file */
1193-
result = git_futils_readbuffer(&contents, cfg->file.path);
1194+
error = git_futils_readbuffer(&contents, cfg->file.path);
11941195
}
1196+
if (error < 0 && error != GIT_ENOTFOUND)
1197+
goto done;
11951198

1196-
/* Initialise the reading position */
1197-
if (result == 0 || result == GIT_ENOTFOUND) {
1198-
git_parse_ctx_init(&reader.ctx, contents.ptr, contents.size);
1199-
} else {
1200-
git_filebuf_cleanup(&file);
1201-
return -1; /* OS error when reading the file */
1202-
}
1199+
if ((git_config_parser_init(&parser, cfg->file.path, contents.ptr, contents.size)) < 0)
1200+
goto done;
12031201

12041202
ldot = strrchr(key, '.');
12051203
name = ldot + 1;
@@ -1212,30 +1210,16 @@ static int config_write(diskfile_backend *cfg, const char *orig_key, const char
12121210
GIT_ERROR_CHECK_ALLOC(orig_section);
12131211

12141212
write_data.buf = &buf;
1215-
git_buf_init(&write_data.buffered_comment, 0);
12161213
write_data.orig_section = orig_section;
12171214
write_data.section = section;
1218-
write_data.in_section = 0;
1219-
write_data.preg_replaced = 0;
12201215
write_data.orig_name = orig_name;
12211216
write_data.name = name;
12221217
write_data.preg = preg;
12231218
write_data.value = value;
12241219

1225-
result = git_config_parse(&reader,
1226-
write_on_section,
1227-
write_on_variable,
1228-
write_on_comment,
1229-
write_on_eof,
1230-
&write_data);
1231-
git__free(section);
1232-
git__free(orig_section);
1233-
git_buf_dispose(&write_data.buffered_comment);
1234-
1235-
if (result < 0) {
1236-
git_filebuf_cleanup(&file);
1220+
if ((error = git_config_parse(&parser, write_on_section, write_on_variable,
1221+
write_on_comment, write_on_eof, &write_data)) < 0)
12371222
goto done;
1238-
}
12391223

12401224
if (cfg->locked) {
12411225
size_t len = buf.asize;
@@ -1245,16 +1229,21 @@ static int config_write(diskfile_backend *cfg, const char *orig_key, const char
12451229
} else {
12461230
git_filebuf_write(&file, git_buf_cstr(&buf), git_buf_len(&buf));
12471231

1248-
if ((result = git_filebuf_commit(&file)) < 0)
1232+
if ((error = git_filebuf_commit(&file)) < 0)
12491233
goto done;
12501234

1251-
if ((result = config_refresh_from_buffer(&cfg->header.parent, buf.ptr, buf.size)) < 0)
1235+
if ((error = config_refresh_from_buffer(&cfg->header.parent, buf.ptr, buf.size)) < 0)
12521236
goto done;
12531237
}
12541238

12551239
done:
1240+
git__free(section);
1241+
git__free(orig_section);
1242+
git_buf_dispose(&write_data.buffered_comment);
12561243
git_buf_dispose(&buf);
12571244
git_buf_dispose(&contents);
1258-
git_parse_ctx_clear(&reader.ctx);
1259-
return result;
1245+
git_filebuf_cleanup(&file);
1246+
git_config_parser_dispose(&parser);
1247+
1248+
return error;
12601249
}

src/config_mem.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,20 +78,24 @@ static int read_variable_cb(
7878
static int config_memory_open(git_config_backend *backend, git_config_level_t level, const git_repository *repo)
7979
{
8080
config_memory_backend *memory_backend = (config_memory_backend *) backend;
81+
git_config_parser parser = GIT_PARSE_CTX_INIT;
8182
config_memory_parse_data parse_data;
82-
git_config_parser reader;
83+
int error;
8384

8485
GIT_UNUSED(repo);
8586

86-
if (memory_backend->cfg.size == 0)
87-
return 0;
88-
89-
git_parse_ctx_init(&reader.ctx, memory_backend->cfg.ptr, memory_backend->cfg.size);
90-
reader.file = NULL;
87+
if ((error = git_config_parser_init(&parser, "in-memory", memory_backend->cfg.ptr,
88+
memory_backend->cfg.size)) < 0)
89+
goto out;
9190
parse_data.entries = memory_backend->entries;
9291
parse_data.level = level;
9392

94-
return git_config_parse(&reader, NULL, read_variable_cb, NULL, NULL, &parse_data);
93+
if ((error = git_config_parse(&parser, NULL, read_variable_cb, NULL, NULL, &parse_data)) < 0)
94+
goto out;
95+
96+
out:
97+
git_config_parser_dispose(&parser);
98+
return error;
9599
}
96100

97101
static int config_memory_get(git_config_backend *backend, const char *key, git_config_entry **out)

0 commit comments

Comments
 (0)