diff --git a/include/libweston/config-parser.h b/include/libweston/config-parser.h index 343ff53d..81f28b59 100644 --- a/include/libweston/config-parser.h +++ b/include/libweston/config-parser.h @@ -88,6 +88,9 @@ weston_config_section_get_bool(struct weston_config_section *section, const char * weston_config_get_name_from_env(void); +struct weston_config * +weston_config_parse_fp(FILE *file); + struct weston_config * weston_config_parse(const char *name); diff --git a/shared/config-parser.c b/shared/config-parser.c index c19baa0d..30779ae4 100644 --- a/shared/config-parser.c +++ b/shared/config-parser.c @@ -381,41 +381,15 @@ section_add_entry(struct weston_config_section *section, return entry; } -WL_EXPORT struct weston_config * -weston_config_parse(const char *name) +static bool +weston_config_parse_internal(struct weston_config *config, FILE *fp) { - FILE *fp; - char line[512], *p; - struct stat filestat; - struct weston_config *config; struct weston_config_section *section = NULL; - int i, fd; - - config = zalloc(sizeof *config); - if (config == NULL) - return NULL; + char line[512], *p; + int i; wl_list_init(&config->section_list); - fd = open_config_file(config, name); - if (fd == -1) { - free(config); - return NULL; - } - - if (fstat(fd, &filestat) < 0 || - !S_ISREG(filestat.st_mode)) { - close(fd); - free(config); - return NULL; - } - - fp = fdopen(fd, "r"); - if (fp == NULL) { - free(config); - return NULL; - } - while (fgets(line, sizeof line, fp)) { switch (line[0]) { case '#': @@ -426,9 +400,7 @@ weston_config_parse(const char *name) if (!p || p[1] != '\n') { fprintf(stderr, "malformed " "section header: %s\n", line); - fclose(fp); - weston_config_destroy(config); - return NULL; + return false; } p[0] = '\0'; section = config_add_section(config, &line[1]); @@ -438,9 +410,7 @@ weston_config_parse(const char *name) if (!p || p == line || !section) { fprintf(stderr, "malformed " "config line: %s\n", line); - fclose(fp); - weston_config_destroy(config); - return NULL; + return false; } p[0] = '\0'; @@ -457,8 +427,67 @@ weston_config_parse(const char *name) } } + return true; +} + +WESTON_EXPORT_FOR_TESTS struct weston_config * +weston_config_parse_fp(FILE *file) +{ + struct weston_config *config = zalloc(sizeof(*config)); + + if (config == NULL) + return NULL; + + if (!weston_config_parse_internal(config, file)) { + weston_config_destroy(config); + return NULL; + } + + return config; +} + +WL_EXPORT struct weston_config * +weston_config_parse(const char *name) +{ + FILE *fp; + struct stat filestat; + struct weston_config *config; + int fd; + bool ret; + + config = zalloc(sizeof *config); + if (config == NULL) + return NULL; + + fd = open_config_file(config, name); + if (fd == -1) { + free(config); + return NULL; + } + + if (fstat(fd, &filestat) < 0 || + !S_ISREG(filestat.st_mode)) { + close(fd); + free(config); + return NULL; + } + + fp = fdopen(fd, "r"); + if (fp == NULL) { + close(fd); + free(config); + return NULL; + } + + ret = weston_config_parse_internal(config, fp); + fclose(fp); + if (!ret) { + weston_config_destroy(config); + return NULL; + } + return config; } diff --git a/tests/config-parser-test.c b/tests/config-parser-test.c index 626c01d9..33ad5d0b 100644 --- a/tests/config-parser-test.c +++ b/tests/config-parser-test.c @@ -48,23 +48,25 @@ static struct weston_config * load_config(const char *text) { struct weston_config *config = NULL; - int len = 0; - int fd = -1; - char file[] = "/tmp/weston-config-parser-test-XXXXXX"; + char *content = NULL; + size_t file_len = 0; + int write_len; + FILE *file; - ZUC_ASSERTG_NOT_NULL(text, out); + file = open_memstream(&content, &file_len); + ZUC_ASSERTG_NOT_NULL(file, out); - fd = mkstemp(file); - ZUC_ASSERTG_NE(-1, fd, out); + write_len = fwrite(text, 1, strlen(text), file); + ZUC_ASSERTG_EQ((int)strlen(text), write_len, out_close); - len = write(fd, text, strlen(text)); - ZUC_ASSERTG_EQ((int)strlen(text), len, out_close); + ZUC_ASSERTG_EQ(fflush(file), 0, out_close); + fseek(file, 0L, SEEK_SET); - config = weston_config_parse(file); + config = weston_config_parse_fp(file); out_close: - close(fd); - unlink(file); + fclose(file); + free(content); out: return config; }