[kvm-unit-tests PATCH 2/2] lib/util,arm,powerpc: replace parse_keyval with better helpers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



A common pattern was to scan through all argv strings to find key or
key=val.  parse_keyval used to return val as long, but another function
needed to check the key.  New functions do both at once.

parse_keyval was replaced with different parse_keyval, so callers needed
to be updated.  While at it, I changed the meaning of arguments to
powerpc/rtas.c to make the code simpler.  And removing aborts is a
subtle preparation for a patch that reports SKIP when no tests were run
and they weren't necessary even now.

Signed-off-by: Radim Krčmář <rkrcmar@xxxxxxxxxx>
---
 arm/selftest.c        | 36 +++++++++++++++---------------------
 lib/util.c            | 44 ++++++++++++++++++++++++++++++++++++--------
 lib/util.h            | 28 ++++++++++++++++++----------
 powerpc/emulator.c    |  9 ++-------
 powerpc/rtas.c        | 33 ++++++++++-----------------------
 powerpc/selftest.c    | 40 +++++++++++++++-------------------------
 powerpc/unittests.cfg |  2 +-
 7 files changed, 97 insertions(+), 95 deletions(-)

diff --git a/arm/selftest.c b/arm/selftest.c
index 5656f2bb1cc8..3ecfb637d673 100644
--- a/arm/selftest.c
+++ b/arm/selftest.c
@@ -21,33 +21,27 @@
 
 static void check_setup(int argc, char **argv)
 {
-	int nr_tests = 0, len, i;
+	int nr_tests = 0;
 	long val;
 
-	for (i = 0; i < argc; ++i) {
+	if (parse_keyval(argc, argv, "mem", &val)) {
+		report_prefix_push("mem");
 
-		len = parse_keyval(argv[i], &val);
-		if (len == -1)
-			continue;
+		phys_addr_t memsize = PHYS_END - PHYS_OFFSET;
+		phys_addr_t expected = ((phys_addr_t)val)*1024*1024;
 
-		argv[i][len] = '\0';
-		report_prefix_push(argv[i]);
+		report("size = %d MB", memsize == expected,
+						memsize/1024/1024);
+		++nr_tests;
+		report_prefix_pop();
+	}
 
-		if (strcmp(argv[i], "mem") == 0) {
+	if (parse_keyval(argc, argv, "smp", &val)) {
+		report_prefix_push("smp");
 
-			phys_addr_t memsize = PHYS_END - PHYS_OFFSET;
-			phys_addr_t expected = ((phys_addr_t)val)*1024*1024;
-
-			report("size = %d MB", memsize == expected,
-							memsize/1024/1024);
-			++nr_tests;
-
-		} else if (strcmp(argv[i], "smp") == 0) {
-
-			report("nr_cpus = %d", nr_cpus == (int)val, nr_cpus);
-			++nr_tests;
-		}
+		report("nr_cpus = %d", nr_cpus == (int)val, nr_cpus);
 
+		++nr_tests;
 		report_prefix_pop();
 	}
 
@@ -331,7 +325,7 @@ int main(int argc, char **argv)
 
 	if (strcmp(argv[1], "setup") == 0) {
 
-		check_setup(argc-2, &argv[2]);
+		check_setup(argc-1, &argv[1]);
 
 	} else if (strcmp(argv[1], "vectors-kernel") == 0) {
 
diff --git a/lib/util.c b/lib/util.c
index 69b18100c972..157138060d8c 100644
--- a/lib/util.c
+++ b/lib/util.c
@@ -4,15 +4,43 @@
  * This work is licensed under the terms of the GNU LGPL, version 2.
  */
 #include <libcflat.h>
+#include <util.h>
 
-int parse_keyval(char *s, long *val)
+bool parse_keyval(int argc, char **argv, char *key, long *val)
 {
-	char *p;
+	char *str = find_keyval(argc, argv, key);
+	bool is_keyval = str && str != key;
 
-	p = strchr(s, '=');
-	if (!p)
-		return -1;
-
-	*val = atol(p+1);
-	return p - s;
+	if (is_keyval)
+		*val = atol(str);
+	return is_keyval;
+}
+
+long atol_keyval(int argc, char **argv, char *key)
+{
+	long val;
+	bool is_keyval = parse_keyval(argc, argv, key, &val);
+
+	return is_keyval ? val : 0;
+}
+
+bool find_key(int argc, char **argv, char *key) {
+	return find_keyval(argc, argv, key) == key;
+}
+
+char * find_keyval(int argc, char **argv, char *key)
+{
+	int i;
+	size_t keylen = strlen(key);
+
+	for (i = 1; i < argc; i++) {
+		if (keylen > 0 && strncmp(argv[i], key, keylen - 1))
+			continue;
+		if (argv[i][keylen] == '\0')
+			return key;
+		if (argv[i][keylen] == '=')
+			return argv[i] + keylen + 1;
+	}
+
+	return NULL;
 }
diff --git a/lib/util.h b/lib/util.h
index 4c4b44132277..1eb0067dc8d7 100644
--- a/lib/util.h
+++ b/lib/util.h
@@ -8,16 +8,24 @@
  * This work is licensed under the terms of the GNU LGPL, version 2.
  */
 
-/*
- * parse_keyval extracts the integer from a string formatted as
- * string=integer. This is useful for passing expected values to
- * the unit test on the command line, i.e. it helps parse QEMU
- * command lines that include something like -append var1=1 var2=2
- * @s is the input string, likely a command line parameter, and
- * @val is a pointer to where the integer will be stored.
- *
- * Returns the offset of the '=', or -1 if no keyval pair is found.
+/* @argc and @argv are standard arguments to C main.  */
+
+/* parse_keyval returns true if @argv[i] has @key=val format and parse @val;
+ * returns false otherwise.
  */
-extern int parse_keyval(char *s, long *val);
+bool parse_keyval(int argc, char **argv, char *key, long *val);
+
+/* atol_keyval returns parsed val if @argv[i] has @key=val format; returns 0
+ * otherwise.
+ */
+long atol_keyval(int argc, char **argv, char *key);
+
+/* find_key decides whether @key is equal @argv[i]. */
+bool find_key(int argc, char **argv, char *key);
+
+/* find_keyval returns key if @key is equal to @argv[i]; returns pointer to val
+ * if @argv[i] has @key=val format; returns NULL otherwise.
+ */
+char * find_keyval(int argc, char **argv, char *key);
 
 #endif
diff --git a/powerpc/emulator.c b/powerpc/emulator.c
index 25018a57463b..384f927f4f71 100644
--- a/powerpc/emulator.c
+++ b/powerpc/emulator.c
@@ -4,6 +4,7 @@
 
 #include <libcflat.h>
 #include <asm/processor.h>
+#include <util.h>
 
 static int verbose;
 static int volatile is_invalid;
@@ -219,16 +220,10 @@ static void test_lswx(void)
 
 int main(int argc, char **argv)
 {
-	int i;
-
 	handle_exception(0x700, program_check_handler, (void *)&is_invalid);
 	handle_exception(0x600, alignment_handler, (void *)&alignment);
 
-	for (i = 1; i < argc; i++) {
-		if (strcmp(argv[i], "-v") == 0) {
-			verbose = 1;
-		}
-	}
+	verbose = find_key(argc, argv, "-v");
 
 	report_prefix_push("emulator");
 
diff --git a/powerpc/rtas.c b/powerpc/rtas.c
index 1b1e9c753ef1..431adf54f0af 100644
--- a/powerpc/rtas.c
+++ b/powerpc/rtas.c
@@ -44,6 +44,8 @@ static void check_get_time_of_day(unsigned long start)
 	int now[8];
 	unsigned long t1, t2, count;
 
+	report_prefix_push("get-time-of-day");
+
 	token = rtas_token("get-time-of-day");
 	report("token available", token != RTAS_UNKNOWN_SERVICE);
 	if (token == RTAS_UNKNOWN_SERVICE)
@@ -70,6 +72,8 @@ static void check_get_time_of_day(unsigned long start)
 		count++;
 	} while (t1 + DELAY > t2 && count < MAX_LOOP);
 	report("running", t1 + DELAY <= t2);
+
+	report_prefix_pop();
 }
 
 static void check_set_time_of_day(void)
@@ -79,6 +83,8 @@ static void check_set_time_of_day(void)
 	int date[8];
 	unsigned long t1, t2, count;
 
+	report_prefix_push("set-time-of-day");
+
 	token = rtas_token("set-time-of-day");
 	report("token available", token != RTAS_UNKNOWN_SERVICE);
 	if (token == RTAS_UNKNOWN_SERVICE)
@@ -106,6 +112,8 @@ static void check_set_time_of_day(void)
 		count++;
 	} while (t1 + DELAY > t2 && count < MAX_LOOP);
 	report("running", t1 + DELAY <= t2);
+
+	report_prefix_pop();
 }
 
 int main(int argc, char **argv)
@@ -115,33 +123,12 @@ int main(int argc, char **argv)
 
 	report_prefix_push("rtas");
 
-	if (argc < 2)
-		report_abort("no test specified");
-
-	report_prefix_push(argv[1]);
-
-	if (strcmp(argv[1], "get-time-of-day") == 0) {
-
-		len = parse_keyval(argv[2], &val);
-		if (len == -1) {
-			printf("Missing parameter \"date\"\n");
-			abort();
-		}
-		argv[2][len] = '\0';
-
+	if (parse_keyval(argc, argv, "get-time-of-day", &val))
 		check_get_time_of_day(val);
 
-	} else if (strcmp(argv[1], "set-time-of-day") == 0) {
-
+	if (find_key(argc, argv, "set-time-of-day"))
 		check_set_time_of_day();
 
-	} else {
-		printf("Unknown subtest\n");
-		abort();
-	}
-
-	report_prefix_pop();
-
 	report_prefix_pop();
 
 	return report_summary();
diff --git a/powerpc/selftest.c b/powerpc/selftest.c
index 8c5ff0ac889d..09856486bac5 100644
--- a/powerpc/selftest.c
+++ b/powerpc/selftest.c
@@ -11,33 +11,28 @@
 
 static void check_setup(int argc, char **argv)
 {
-	int nr_tests = 0, len, i;
+	int nr_tests = 0;
 	long val;
 
-	for (i = 0; i < argc; ++i) {
+	if (parse_keyval(argc, argv, "mem", &val)) {
+		report_prefix_push("mem");
 
-		len = parse_keyval(argv[i], &val);
-		if (len == -1)
-			continue;
+		phys_addr_t memsize = PHYSICAL_END - PHYSICAL_START;
+		phys_addr_t expected = ((phys_addr_t)val)*1024*1024;
 
-		argv[i][len] = '\0';
-		report_prefix_push(argv[i]);
+		report("size = %d MB", memsize == expected,
+						memsize/1024/1024);
 
-		if (strcmp(argv[i], "mem") == 0) {
+		++nr_tests;
+		report_prefix_pop();
+	}
 
-			phys_addr_t memsize = PHYSICAL_END - PHYSICAL_START;
-			phys_addr_t expected = ((phys_addr_t)val)*1024*1024;
+	if (parse_keyval(argc, argv, "smp", &val)) {
+		report_prefix_push("smp");
 
-			report("size = %d MB", memsize == expected,
-							memsize/1024/1024);
-			++nr_tests;
-
-		} else if (strcmp(argv[i], "smp") == 0) {
-
-			report("nr_cpus = %d", nr_cpus == (int)val, nr_cpus);
-			++nr_tests;
-		}
+		report("nr_cpus = %d", nr_cpus == (int)val, nr_cpus);
 
+		++nr_tests;
 		report_prefix_pop();
 	}
 
@@ -49,14 +44,9 @@ int main(int argc, char **argv)
 {
 	report_prefix_push("selftest");
 
-	if (argc < 2)
-		report_abort("no test specified");
-
-	report_prefix_push(argv[1]);
-
 	if (strcmp(argv[1], "setup") == 0) {
 
-		check_setup(argc-2, &argv[2]);
+		check_setup(argc-1, &argv[1]);
 
 	}
 
diff --git a/powerpc/unittests.cfg b/powerpc/unittests.cfg
index ed4fdbe64909..fe5db7e302bb 100644
--- a/powerpc/unittests.cfg
+++ b/powerpc/unittests.cfg
@@ -39,7 +39,7 @@ file = spapr_hcall.elf
 [rtas-get-time-of-day]
 file = rtas.elf
 timeout = 5
-extra_params = -append "get-time-of-day date=$(date +%s)"
+extra_params = -append "get-time-of-day=$(date +%s)"
 groups = rtas
 
 [rtas-set-time-of-day]
-- 
2.8.2

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux