This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 04/21] Add -fself-test-regex=


This patch adds a way to only run a subset of the tests,
by matching a regex against test names.

This can also be used to run just one test.

gcc/ChangeLog:
	* common.opt (fself-test-regex=): New option.
	* selftest.c: Include diagnostic.h, xregex.h, options.h.
	(get_regerror): New function.
	(selftest::run_all_tests): Rename to...
	(selftest::run_tests): ...this, and add param REGEX_PATTERN,
	using it to filter the tests if non-NULL.
	* selftest.h (selftest::run_all_tests): Rename to...
	(selftest::run_tests): ...this, adding param REGEX_PATTERN.
	* toplev.c (toplev::run_self_tests): Update for above changes.
---
 gcc/common.opt |  4 ++++
 gcc/selftest.c | 45 ++++++++++++++++++++++++++++++++++++++++++---
 gcc/selftest.h |  7 ++++---
 gcc/toplev.c   |  2 +-
 4 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/gcc/common.opt b/gcc/common.opt
index 95376bf..6aaf8e6 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2061,6 +2061,10 @@ fself-test
 Common Var(flag_self_test)
 Run self-tests.
 
+fself-test-regex=
+Common RejectNegative Joined Var(self_test_regex)
+Run self-tests matching the given regex.
+
 fsel-sched-pipelining
 Common Report Var(flag_sel_sched_pipelining) Init(0) Optimization
 Perform software pipelining of inner loops during selective scheduling.
diff --git a/gcc/selftest.c b/gcc/selftest.c
index 42e07e3..ada0b9b 100644
--- a/gcc/selftest.c
+++ b/gcc/selftest.c
@@ -21,12 +21,15 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "selftest.h"
+#include "diagnostic.h"
+#include "xregex.h"
+#include "options.h"
 
 #if CHECKING_P
 
 using namespace selftest;
 
-/* Helper function for ::selftest::run_all_tests.  */
+/* Helper function for ::selftest::run_tests.  */
 
 static int
 test_comparator (const void *p1, const void *p2)
@@ -36,11 +39,24 @@ test_comparator (const void *p1, const void *p2)
   return strcmp (t1->get_name (), t2->get_name ());
 }
 
-/* Locate and run all tests.
+/* Generate an error message describing a failed attempt to compile a
+   regex.  The return value should be freed.  */
+
+static char *
+get_regerror (int errcode, regex_t *compiled)
+{
+  size_t length = regerror (errcode, compiled, NULL, 0);
+  char *buffer = (char *)xmalloc (length);
+  (void) regerror (errcode, compiled, buffer, length);
+  return buffer;
+}
+
+/* Locate and run tests.  If REGEX_PATTERN is NULL, all tests are run.
+   Otherwise, only tests with names matching the regex are run.
    Return the number of failures that occurred.  */
 
 int
-selftest::run_all_tests ()
+selftest::run_tests (const char *regex_pattern)
 {
   /* Create all the tests, in an arbitrary order (based on
      the order of construction of the global "registrator" instances).  */
@@ -57,11 +73,31 @@ selftest::run_all_tests ()
   /* Sort the tests into a predictable order.  */
   tests.qsort (test_comparator);
 
+  regex_t regex;
+  if (regex_pattern)
+    {
+      int errcode = regcomp (&regex, regex_pattern, 0);
+      if (errcode)
+	{
+	  char *errmsg = get_regerror (errcode, &regex);
+	  error ("error compiling regex pattern %qs: %s", regex_pattern, errmsg);
+	  free (errmsg);
+	  return 1;
+	}
+    }
+
   /* Run all the tests, in order.  */
   unsigned i;
   test *t;
   FOR_EACH_VEC_ELT (tests, i, t)
     {
+      if (regex_pattern)
+	{
+	  int err = regexec (&regex, t->get_name (), 0, NULL, 0);
+	  if (err)
+	    /* Test did not match.  */
+	    continue;
+	}
       r.begin_test (t);
       t->run ();
       r.end_test (t);
@@ -71,6 +107,9 @@ selftest::run_all_tests ()
   FOR_EACH_VEC_ELT (tests, i, t)
     delete t;
 
+  if (regex_pattern)
+    regfree (&regex);
+
   return r.get_num_failures ();
 }
 
diff --git a/gcc/selftest.h b/gcc/selftest.h
index 95262ce..aa0232a 100644
--- a/gcc/selftest.h
+++ b/gcc/selftest.h
@@ -31,9 +31,10 @@ class test;
 class runner;
 class registrator;
 
-/* The entrypoint for running all tests.  */
+/* The entrypoint for running all tests, or all tests matching
+   REGEX_PATTERN.  */
 
-extern int run_all_tests ();
+extern int run_tests (const char *regex_pattern);
 
 /* The class ::selftest::runner is responsible for gathering results,
    and for output.  */
@@ -93,7 +94,7 @@ class test
    Global instances are created via the REGISTER_TEST below.
    The constructor runs before main, wiring them up into a
    singly-linked list, which can be traversed by
-   ::selftest::run_all_tests.  */
+   ::selftest::run_tests.  */
 
 class registrator
 {
diff --git a/gcc/toplev.c b/gcc/toplev.c
index ccb9c79..e240b98 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -2069,7 +2069,7 @@ toplev::run_self_tests ()
   bitmap_obstack_initialize (NULL);
 
   /* Run the tests.  */
-  int result = ::selftest::run_all_tests ();
+  int result = ::selftest::run_tests (self_test_regex);
 
   /* Ensure that a test failure leads to the process exiting with
      a non-zero exit code.  */
-- 
1.8.5.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]