[CRIU] [PATCH 24/24] compel cli: make -p optional

Kir Kolyshkin kir at openvz.org
Sat Dec 17 03:22:17 PST 2016


Yet another nail in the coffin of compel cli usage complexity.

Since commit cd1c9d9 ("compel: simplify usage wrt ids") landed,
it became obvious that the newly introduced -p option can be
made optional. First, prefix value is not very important;
second, it can be easily generated from the input (or output)
file name.

This is what this commit does, also trying to check that
the resulting prefix is adeqate for using in C code. In case
it is not (say, file names used are 1.po 1.h), an error
is printed, suggesting to use --prefix.

The commit also makes use of this functionality by removing
-p option from compel/test/infect and criu/pie Makefiles.

While at it, let's also remove -l 4 and the kludge of hiding it.
If the output generated by this is ever needed, one can easily
run "compel hgen -l4 ..." manually.

Signed-off-by: Kir Kolyshkin <kir at openvz.org>
---
 compel/src/main.c           | 81 +++++++++++++++++++++++++++++++++++++++++++--
 compel/test/infect/Makefile |  4 +--
 criu/pie/Makefile           |  9 +----
 3 files changed, 80 insertions(+), 14 deletions(-)

diff --git a/compel/src/main.c b/compel/src/main.c
index fe91d1f..36f0c72 100644
--- a/compel/src/main.c
+++ b/compel/src/main.c
@@ -5,6 +5,7 @@
 #include <stdint.h>
 #include <getopt.h>
 #include <string.h>
+#include <ctype.h>
 
 #include <fcntl.h>
 
@@ -122,7 +123,7 @@ static int usage(int rc) {
 "Usage:\n"
 "  compel [--compat] includes | cflags | ldflags | plugins\n"
 "  compel [--compat] [--static] libs\n"
-"  compel -f FILE -o FILE -p NAME [-l N] hgen\n"
+"  compel -f FILE -o FILE [-p NAME] [-l N] hgen\n"
 "    -f, --file FILE		input (parasite object) file name\n"
 "    -o, --output FILE		output (header) file name\n"
 "    -p, --prefix NAME		prefix for var names\n"
@@ -213,6 +214,73 @@ static int print_libs(bool is_static)
 	return 0;
 }
 
+/* Extracts the file name (removing directory path and suffix,
+ * and checks the result for being a valid C identifier
+ * (replacing - with _ along the way).
+ *
+ * If everything went fine, return the resulting string,
+ * otherwise NULL.
+ *
+ * Example: get_prefix("./some/path/to/file.c") ==> "file"
+ */
+static char *gen_prefix(const char *path)
+{
+	const char *p1 = NULL, *p2 = NULL;
+	size_t len;
+	int i;
+	char *p, *ret;
+
+	len = strlen(path);
+	if (len == 0)
+		return NULL;
+
+	// Find the last slash (p1)
+	// and  the first dot after it (p2)
+	for (i = len - 1; i >= 0; i--) {
+		if (!p1 && path[i] == '.') {
+			p2 = path + i - 1;
+		}
+		else if (!p1 && path[i] == '/') {
+			p1 = path + i + 1;
+			break;
+		}
+	}
+
+	if (!p1) // no slash in path
+		p1 = path;
+	if (!p2) // no dot (after slash)
+		p2 = path + len;
+
+	len = p2 - p1 + 1;
+	if (len < 1)
+		return NULL;
+
+	ret = strndup(p1, len);
+
+	// Now, check if we got a valid C identifier. We don't need to care
+	// about C reserved keywords, as this is only used as a prefix.
+	for (p = ret; *p != '\0'; p++) {
+		if (isalpha(*p))
+			continue;
+		// digit is fine, except the first character
+		if (isdigit(*p) && p > ret)
+			continue;
+		// only allowed special character is _
+		if (*p == '_')
+			continue;
+		// as a courtesy, replace - with _
+		if (*p == '-') {
+			*p = '_';
+			continue;
+		}
+		// invalid character!
+		free(ret);
+		return NULL;
+	}
+
+	return ret;
+}
+
 int main(int argc, char *argv[])
 {
 	int log_level = DEFAULT_LOGLEVEL;
@@ -318,8 +386,15 @@ int main(int argc, char *argv[])
 			return usage(1);
 		}
 		if (!opts.prefix) {
-			fprintf(stderr, "Error: option --prefix required\n");
-			return usage(1);
+			// prefix not provided, let's autogenerate
+			opts.prefix = gen_prefix(opts.input_filename);
+			if (!opts.prefix)
+				opts.prefix = gen_prefix(opts.output_filename);
+			if (!opts.prefix) {
+				fprintf(stderr, "Error: can't autogenerate "
+						"prefix (supply --prefix)");
+				return 2;
+			}
 		}
 		compel_log_init(&cli_log, log_level);
 		return piegen();
diff --git a/compel/test/infect/Makefile b/compel/test/infect/Makefile
index fa966ac..4dedf33 100644
--- a/compel/test/infect/Makefile
+++ b/compel/test/infect/Makefile
@@ -19,9 +19,7 @@ spy: spy.c parasite.h
 	$(CC) $(CFLAGS) $(shell $(COMPEL) includes) -o $@ $< $(shell $(COMPEL) --static libs)
 
 parasite.h: parasite.po
-	$(COMPEL) hgen -f $^ -l 4		\
-		-p parasite			\
-		-o $@
+	$(COMPEL) hgen -o $@ -f $<
 
 parasite.po: parasite.o
 	ld $(shell $(COMPEL) ldflags) -o $@ $^ $(shell $(COMPEL) plugins)
diff --git a/criu/pie/Makefile b/criu/pie/Makefile
index 2083271..f16d325 100644
--- a/criu/pie/Makefile
+++ b/criu/pie/Makefile
@@ -47,10 +47,6 @@ BLOBS		+= $(obj)/restorer-blob.h $(obj)/parasite-blob.h
 
 target-name = $(patsubst criu/pie/%-blob.h,%,$(1))
 
-ifeq ($(strip $(V)),)
-        piegen_stdout := >/dev/null
-endif
-
 $(obj)/restorer.built-in.o: $(compel_std)
 $(obj)/parasite.built-in.o: $(compel_std)
 $(obj)/%.built-in.bin.o: $(obj)/%.built-in.o $(obj)/pie.lib.a
@@ -59,10 +55,7 @@ $(obj)/%.built-in.bin.o: $(obj)/%.built-in.o $(obj)/pie.lib.a
 
 $(obj)/%-blob.h: $(obj)/%.built-in.bin.o $(SRC_DIR)/compel/compel-host-bin
 	$(call msg-gen, $@)
-	$(Q) $(COMPEL_BIN) hgen -f $<		\
-		-l 4				\
-		-p $(call target-name,$@)	\
-		-o $@ $(piegen_stdout)
+	$(Q) $(COMPEL_BIN) hgen -f $< -o $@
 
 all-y += $(BLOBS)
 # blobs and pields are in cleanup, rather than in mrproper because
-- 
2.7.4



More information about the CRIU mailing list