[ltrace-commits] 01/02: Add an ability to import config files into other config files
Petr Machata
pmachata-guest at moszumanska.debian.org
Mon Apr 20 08:18:27 UTC 2015
This is an automated email from the git hooks/post-receive script.
pmachata-guest pushed a commit to branch master
in repository ltrace.
commit defa32014bcf4d870682384f58da155f02022e01
Author: Роман Донченко <dpb at corrigendum.ru>
Date: Mon Apr 20 03:39:24 2015 +0300
Add an ability to import config files into other config files
Handy for sharing declarations between libraries.
---
forward.h | 1 +
prototype.c | 2 +-
read_config_file.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
read_config_file.h | 3 +-
4 files changed, 87 insertions(+), 5 deletions(-)
diff --git a/forward.h b/forward.h
index 58d8f05..7bdc98c 100644
--- a/forward.h
+++ b/forward.h
@@ -33,6 +33,7 @@ struct param;
struct param_enum;
struct process;
struct protolib;
+struct protolib_cache;
struct prototype;
struct timedelta;
struct value;
diff --git a/prototype.c b/prototype.c
index fa52ff3..1383433 100644
--- a/prototype.c
+++ b/prototype.c
@@ -636,7 +636,7 @@ protolib_cache_file(struct protolib_cache *cache,
struct protolib *new_plib = build_default_config(cache, filename);
if (new_plib == NULL
- || read_config_file(stream, filename, new_plib) < 0) {
+ || read_config_file(stream, filename, cache, new_plib) < 0) {
fclose(stream);
if (own_filename)
free((char *) filename);
diff --git a/read_config_file.c b/read_config_file.c
index ed2de09..45daa9c 100644
--- a/read_config_file.c
+++ b/read_config_file.c
@@ -205,6 +205,42 @@ parse_char(struct locus *loc, char **str, char expected)
return 0;
}
+static char *
+parse_string_literal(struct locus *loc, char **str)
+{
+ if (parse_char(loc, str, '"') < 0)
+ return NULL;
+
+ size_t len = strcspn(*str, "\"\n\\");
+ char terminator = (*str)[len];
+
+ if (terminator == '\0' || terminator == '\n') {
+ report_error(loc->filename, loc->line_no, "unmatched quote");
+ return NULL;
+ }
+
+ if (terminator == '\\') {
+ /* Strings are currently only used for filenames, where
+ * there's usually nothing to escape. Nevertheless, we reserve
+ * the backslash in case strings become used in other contexts
+ * where escaping is necessary. */
+ report_error(loc->filename, loc->line_no,
+ "backslashes in string literals reserved for future use");
+ return NULL;
+ }
+
+ char *result = malloc(len + 1);
+ if (!result) {
+ report_error(loc->filename, loc->line_no,
+ "malloc: %s", strerror(errno));
+ return NULL;
+ }
+ memcpy(result, *str, len);
+ result[len] = '\0';
+ (*str) += len + 1;
+ return result;
+}
+
static struct expr_node *parse_argnum(struct locus *loc,
char **str, int *ownp, int zero);
@@ -1039,8 +1075,46 @@ void_to_hidden_int(struct prototype *proto, struct param *param, void *data)
return CBS_CONT;
}
+static void
+parse_import(struct protolib_cache *cache, struct protolib *plib,
+ struct locus *loc, char **str)
+{
+ (*str) += strlen("import");
+ eat_spaces(str);
+
+ char *file_name = parse_string_literal(loc, str);
+ if (!file_name)
+ return;
+
+ eat_spaces(str);
+ if (parse_char(loc, str, ';') < 0) {
+ free(file_name);
+ return;
+ }
+
+ struct protolib *imported;
+
+ if (protolib_cache_maybe_load(cache, file_name, 1, true, &imported) < 0) {
+ free(file_name);
+ return;
+ }
+
+ if (!imported) {
+ report_error(loc->filename, loc->line_no,
+ "\"%s.conf\" not found", file_name);
+ free(file_name);
+ return;
+ }
+
+ if (protolib_add_import(plib, imported) < 0) {
+ report_error(loc->filename, loc->line_no,
+ "import failed");
+ }
+}
+
static int
-process_line(struct protolib *plib, struct locus *loc, char *buf)
+process_line(struct protolib_cache *cache, struct protolib *plib,
+ struct locus *loc, char *buf)
{
char *str = buf;
@@ -1051,6 +1125,11 @@ process_line(struct protolib *plib, struct locus *loc, char *buf)
if (*str == ';' || *str == 0 || *str == '\n' || *str == '#')
return 0;
+ if (try_parse_kwd(&str, "import") >= 0) {
+ parse_import(cache, plib, loc, &str);
+ return 0;
+ }
+
if (try_parse_kwd(&str, "typedef") >= 0) {
parse_typedef(plib, loc, &str);
return 0;
@@ -1185,7 +1264,8 @@ process_line(struct protolib *plib, struct locus *loc, char *buf)
}
int
-read_config_file(FILE *stream, const char *path, struct protolib *plib)
+read_config_file(FILE *stream, const char *path,
+ struct protolib_cache *cache, struct protolib *plib)
{
debug(DEBUG_FUNCTION, "Reading config file `%s'...", path);
@@ -1194,7 +1274,7 @@ read_config_file(FILE *stream, const char *path, struct protolib *plib)
size_t len = 0;
while (getline(&line, &len, stream) >= 0) {
loc.line_no++;
- process_line(plib, &loc, line);
+ process_line(cache, plib, &loc, line);
}
free(line);
diff --git a/read_config_file.h b/read_config_file.h
index 5a72a05..f5fc738 100644
--- a/read_config_file.h
+++ b/read_config_file.h
@@ -23,6 +23,7 @@
#include "forward.h"
-int read_config_file(FILE *stream, const char *name, struct protolib *plib);
+int read_config_file(FILE *stream, const char *name,
+ struct protolib_cache *cache, struct protolib *plib);
#endif /* READ_CONFIG_FILE_H */
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/collab-maint/ltrace.git
More information about the ltrace-commits
mailing list