[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