diff mbox series

[04/17] posix: Adjust glob tests to libsupport

Message ID 1496956411-25594-5-git-send-email-adhemerval.zanella@linaro.org
State Superseded
Headers show
Series posix: glob fixes and refactor | expand

Commit Message

Adhemerval Zanella Netto June 8, 2017, 9:13 p.m. UTC
This patch adjust glob tests to use libsupport.  It also refactor some
tests to move to a more meaningful file name and to gather similar tests
in a common file:

  * move bug-glob3.c tests to tst-glob_basic.c.
  * move bug-glob2.c tests to tst-glob_memory.c
  * move common definitions to tst-glob_common.c.

Checked on x86_64-linux-gnu.

	* posix/Makefile (tests): Remove bug-glob2 and bug-glob3.  Add
	tst-glob_basic and tst-glob_memory.
	* posix/bug-glob3.c: Move to ...
	* posix/tst-glob_basic.c: ... here.
	* posix/bug-glob2.c: Move to ...
	* posix/tst-glob_memory.c: ... here.
	* posix/globtest.c: Use libsupport.
	* posix/tst-gnuglob.c: Likewise.
	* posix/tst-glob_common.c: New file.
---
 posix/Makefile                           |  12 +--
 posix/bug-glob3.c                        |  45 ---------
 posix/globtest.c                         | 163 ++++++++++++++++++-------------
 posix/tst-glob_basic.c                   |  41 ++++++++
 posix/tst-glob_common.c                  | 103 +++++++++++++++++++
 posix/{bug-glob2.c => tst-glob_memory.c} | 100 +++----------------
 posix/tst-gnuglob.c                      | 109 +++------------------
 7 files changed, 270 insertions(+), 303 deletions(-)
 delete mode 100644 posix/bug-glob3.c
 create mode 100644 posix/tst-glob_basic.c
 create mode 100644 posix/tst-glob_common.c
 rename posix/{bug-glob2.c => tst-glob_memory.c} (76%)

-- 
2.7.4
diff mbox series

Patch

diff --git a/posix/Makefile b/posix/Makefile
index 2c0c9f9..1001e54 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -79,7 +79,7 @@  tests		:= test-errno tstgetopt testfnm runtests runptests \
 		   tst-nice tst-nanosleep tst-regex2 \
 		   transbug tst-rxspencer tst-pcre tst-boost \
 		   bug-ga1 tst-vfork1 tst-vfork2 tst-vfork3 tst-waitid \
-		   tst-getaddrinfo2 bug-glob2 bug-glob3 tst-sysconf \
+		   tst-getaddrinfo2 tst-glob_memory tst-glob_basic tst-sysconf \
 		   tst-execvp1 tst-execvp2 tst-execlp1 tst-execlp2 \
 		   tst-execv1 tst-execv2 tst-execl1 tst-execl2 \
 		   tst-execve1 tst-execve2 tst-execle1 tst-execle2 \
@@ -121,7 +121,7 @@  generated += $(addprefix wordexp-test-result, 1 2 3 4 5 6 7 8 9 10) \
 	     tst-getconf.out \
 	     tst-pcre-mem.out tst-pcre.mtrace tst-boost-mem.out \
 	     tst-boost.mtrace bug-ga2.mtrace bug-ga2-mem.out \
-	     bug-glob2.mtrace bug-glob2-mem.out tst-vfork3-mem.out \
+	     tst-glob_memory.mtrace tst-glob_memory-mem.out tst-vfork3-mem.out \
 	     tst-vfork3.mtrace getconf.speclist tst-fnmatch-mem.out \
 	     tst-fnmatch.mtrace bug-regex36.mtrace
 
@@ -139,7 +139,7 @@  tests-special += $(objpfx)bug-regex2-mem.out $(objpfx)bug-regex14-mem.out \
 		 $(objpfx)bug-regex21-mem.out $(objpfx)bug-regex31-mem.out \
 		 $(objpfx)tst-rxspencer-no-utf8-mem.out $(objpfx)tst-pcre-mem.out \
 		 $(objpfx)tst-boost-mem.out $(objpfx)tst-getconf.out \
-		 $(objpfx)bug-glob2-mem.out $(objpfx)tst-vfork3-mem.out \
+		 $(objpfx)tst-glob_memory-mem.out $(objpfx)tst-vfork3-mem.out \
 		 $(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out
 xtests-special += $(objpfx)bug-ga2-mem.out
 endif
@@ -342,10 +342,10 @@  $(objpfx)bug-ga2-mem.out: $(objpfx)bug-ga2.out
 
 bug-ga2-ENV = MALLOC_TRACE=$(objpfx)bug-ga2.mtrace
 
-bug-glob2-ENV = MALLOC_TRACE=$(objpfx)bug-glob2.mtrace
+tst-glob_memory-ENV = MALLOC_TRACE=$(objpfx)tst-glob_memory.mtrace
 
-$(objpfx)bug-glob2-mem.out: $(objpfx)bug-glob2.out
-	$(common-objpfx)malloc/mtrace $(objpfx)bug-glob2.mtrace > $@; \
+$(objpfx)tst-glob_memory-mem.out: $(objpfx)tst-glob_memory.out
+	$(common-objpfx)malloc/mtrace $(objpfx)tst-glob_memory.mtrace > $@; \
 	$(evaluate-test)
 
 $(inst_libexecdir)/getconf: $(inst_bindir)/getconf \
diff --git a/posix/bug-glob3.c b/posix/bug-glob3.c
deleted file mode 100644
index f2fbd70..0000000
--- a/posix/bug-glob3.c
+++ /dev/null
@@ -1,45 +0,0 @@ 
-#include <glob.h>
-#include <stdio.h>
-#include <string.h>
-
-static int
-do_test (void)
-{
-  int result = 0;
-  glob_t g;
-  g.gl_pathc = 0;
-
-  int r = glob ("", 0, NULL, &g);
-  if (r != GLOB_NOMATCH)
-    {
-      puts ("glob (\"\", 0, NULL, &g) did not fail");
-      result = 1;
-    }
-  else if (g.gl_pathc != 0)
-    {
-      puts ("gl_pathc after glob (\"\", 0, NULL, &g) not zero");
-      result = 1;
-    }
-
-  r = glob ("", GLOB_NOCHECK, NULL, &g);
-  if (r != 0)
-    {
-      puts ("glob (\"\", GLOB_NOCHECK, NULL, &g) did fail");
-      result = 1;
-    }
-  else if (g.gl_pathc != 1)
-    {
-      puts ("gl_pathc after glob (\"\", GLOB_NOCHECK, NULL, &g) not 1");
-      result = 1;
-    }
-  else if (strcmp (g.gl_pathv[0], "") != 0)
-    {
-      puts ("gl_pathv[0] after glob (\"\", GLOB_NOCHECK, NULL, &g) not \"\"");
-      result = 1;
-    }
-
-  return result;
-}
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
diff --git a/posix/globtest.c b/posix/globtest.c
index 7ffcb91..e5b5891 100644
--- a/posix/globtest.c
+++ b/posix/globtest.c
@@ -1,4 +1,5 @@ 
-/* Copyright (C) 1997-2017 Free Software Foundation, Inc.
+/* Basic glob tests.  It uses an extenal driver script (tst-glob.sh).
+   Copyright (C) 1997-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -21,77 +22,97 @@ 
 #include <unistd.h>
 #include <glob.h>
 
-int
-main (int argc, char *argv[])
+#include <support/check.h>
+
+#define OPT_BRACE		'b'
+#define OPT_NOCHECK		'c'
+#define OPT_ONLYDIR		'd'
+#define OPT_NOESCAPE		'e'
+#define OPT_ERR			'E'
+#define OPT_NOMAGIC		'g'
+#define OPT_MARK		'm'
+#define OPT_DOOFFS		'o'
+#define OPT_PERIOD		'p'
+#define OPT_QUOTES		'q'
+#define OPT_NOSORT		's'
+#define OPT_TILDE		't'
+#define OPT_TILDE_CHECK		'T'
+
+#define CMDLINE_OPTSTRING "bcdeEgmopqstT"
+
+static int glob_flags = 0;
+static int quotes = 1;
+
+static void
+cmdline_process_function (int c)
 {
-  int i, j;
-  int glob_flags = 0;
-  glob_t g;
-  int quotes = 1;
+  switch (c)
+    {
+    case OPT_BRACE:
+      glob_flags |= GLOB_BRACE;
+      break;
+    case OPT_NOCHECK:
+      glob_flags |= GLOB_NOCHECK;
+      break;
+    case OPT_ONLYDIR:
+      glob_flags |= GLOB_ONLYDIR;
+      break;
+    case OPT_NOESCAPE:
+      glob_flags |= GLOB_NOESCAPE;
+      break;
+    case OPT_ERR:
+      glob_flags |= GLOB_ERR;
+      break;
+    case OPT_NOMAGIC:
+      glob_flags |= GLOB_NOMAGIC;
+      break;
+    case OPT_MARK:
+      glob_flags |= GLOB_MARK;
+      break;
+    case OPT_DOOFFS:
+      glob_flags |= GLOB_DOOFFS;
+      break;
+    case OPT_PERIOD:
+      glob_flags |= GLOB_PERIOD;
+      break;
+    case OPT_QUOTES:
+      quotes = 0;
+      break;
+    case OPT_NOSORT:
+      glob_flags |= GLOB_NOSORT;
+      break;
+    case OPT_TILDE:
+      glob_flags |= GLOB_TILDE;
+      break;
+    case OPT_TILDE_CHECK:
+      glob_flags |= GLOB_TILDE_CHECK;
+      break;
+    }
+}
 
-  g.gl_offs = 0;
+#define CMDLINE_PROCESS	cmdline_process_function
 
-  while ((i = getopt (argc, argv, "bcdeEgmopqstT")) != -1)
-    switch(i)
-      {
-      case 'b':
-	glob_flags |= GLOB_BRACE;
-	break;
-      case 'c':
-	glob_flags |= GLOB_NOCHECK;
-	break;
-      case 'd':
-	glob_flags |= GLOB_ONLYDIR;
-	break;
-      case 'e':
-	glob_flags |= GLOB_NOESCAPE;
-	break;
-      case 'E':
-	glob_flags |= GLOB_ERR;
-	break;
-      case 'g':
-	glob_flags |= GLOB_NOMAGIC;
-	break;
-      case 'm':
-	glob_flags |= GLOB_MARK;
-	break;
-      case 'o':
-	glob_flags |= GLOB_DOOFFS;
-	g.gl_offs = 1;
-	break;
-      case 'p':
-	glob_flags |= GLOB_PERIOD;
-	break;
-      case 'q':
-	quotes = 0;
-	break;
-      case 's':
-	glob_flags |= GLOB_NOSORT;
-	break;
-      case 't':
-	glob_flags |= GLOB_TILDE;
-	break;
-      case 'T':
-	glob_flags |= GLOB_TILDE_CHECK;
-	break;
-      default:
-	exit (-1);
-      }
+static int
+do_test_argv (int argc, char *argv[])
+{
+  int i, j;
+  glob_t g;
 
-  if (optind >= argc || chdir (argv[optind]))
-    exit(1);
+  g.gl_offs = glob_flags & GLOB_DOOFFS ? 1 : 0;
 
-  j = optind + 1;
-  if (optind + 1 >= argc)
-    exit (1);
+  if (argc < 2)
+    FAIL_EXIT1 ("invalid arguments (expecting path for glob)");
+  if (chdir (argv[1]) != 0)
+    FAIL_EXIT1 ("chmod (%s): %m", argv[1]);
 
-  /* Do a glob on each remaining argument.  */
-  for (j = optind + 1; j < argc; j++) {
-    i = glob (argv[j], glob_flags, NULL, &g);
-    if (i != 0)
-      break;
-    glob_flags |= GLOB_APPEND;
-  }
+  /* Do a glob on each argument.  */
+  for (j = 2; j < argc; j++)
+    {
+      i = glob (argv[j], glob_flags, NULL, &g);
+      if (i != 0)
+	break;
+      glob_flags |= GLOB_APPEND;
+    }
 
   /* Was there an error? */
   if (i == GLOB_NOSPACE)
@@ -106,16 +127,18 @@  main (int argc, char *argv[])
   if ((glob_flags & GLOB_DOOFFS) && g.gl_pathv[0] == NULL)
     g.gl_pathv[0] = (char *) "abc";
 
-  /* Print out the names.  Unless otherwise specified, qoute them.  */
+  /* Print out the names.  Unless otherwise specified, quote them.  */
   if (g.gl_pathv)
     {
       for (i = 0; i < g.gl_offs + g.gl_pathc; ++i)
-        printf ("%s%s%s\n", quotes ? "`" : "",
-		g.gl_pathv[i] ? g.gl_pathv[i] : "(null)",
-		quotes ? "'" : "");
+	printf ("%s%s%s\n", quotes ? "`" : "",
+		g.gl_pathv[i] ? g.gl_pathv[i] : "(null)", quotes ? "'" : "");
     }
 
   globfree (&g);
 
   return 0;
 }
+
+#define TEST_FUNCTION_ARGV do_test_argv
+#include <support/test-driver.c>
diff --git a/posix/tst-glob_basic.c b/posix/tst-glob_basic.c
new file mode 100644
index 0000000..64b95a8
--- /dev/null
+++ b/posix/tst-glob_basic.c
@@ -0,0 +1,41 @@ 
+/* Basic glob tests.
+   Copyright (C) 2001-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <glob.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <support/check.h>
+
+static int
+do_test (void)
+{
+  glob_t g;
+  g.gl_pathc = 0;
+
+  TEST_VERIFY_EXIT (glob ("", 0, NULL, &g) == GLOB_NOMATCH);
+  TEST_VERIFY_EXIT (g.gl_pathc == 0);
+
+  TEST_VERIFY_EXIT (glob ("", GLOB_NOCHECK, NULL, &g) == 0);
+  TEST_VERIFY_EXIT (g.gl_pathc == 1);
+  TEST_VERIFY_EXIT (strcmp (g.gl_pathv[0], "") == 0);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/posix/tst-glob_common.c b/posix/tst-glob_common.c
new file mode 100644
index 0000000..b7a66c7
--- /dev/null
+++ b/posix/tst-glob_common.c
@@ -0,0 +1,103 @@ 
+/* Common glob test definition.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+// #define DEBUG
+#ifdef DEBUG
+# define PRINTF(fmt, args...) \
+  do					\
+    {					\
+      int save_errno = errno;		\
+      printf (fmt, ##args);		\
+      errno = save_errno;		\
+    } while (0)
+#else
+# define PRINTF(fmt, args...)
+#endif
+
+struct filesystem_t
+{
+  const char *name;
+  int level;
+  int type;
+  mode_t mode;
+};
+
+static long int
+find_file (const char *s, const struct filesystem_t *filesystem,
+	   size_t nfiles)
+{
+  int level = 1;
+  long int idx = 0;
+
+  while (s[0] == '/')
+    {
+      if (s[1] == '\0')
+	{
+	  s = ".";
+	  break;
+	}
+      ++s;
+    }
+
+  if (strcmp (s, ".") == 0)
+    return 0;
+
+  if (s[0] == '.' && s[1] == '/')
+    s += 2;
+
+  while (*s != '\0')
+    {
+      char *endp = strchrnul (s, '/');
+
+      PRINTF ("looking for %.*s, level %d\n", (int) (endp - s), s, level);
+
+      while (idx < nfiles && filesystem[idx].level >= level)
+	{
+	  if (filesystem[idx].level == level
+	      && memcmp (s, filesystem[idx].name, endp - s) == 0
+	      && filesystem[idx].name[endp - s] == '\0')
+	    break;
+	  ++idx;
+	}
+
+      if (idx == nfiles || filesystem[idx].level < level)
+	{
+	  errno = ENOENT;
+	  return -1;
+	}
+
+      if (*endp == '\0')
+	return idx + 1;
+
+      if (filesystem[idx].type != DT_DIR
+	  && (idx + 1 >= nfiles
+	      || filesystem[idx].level >= filesystem[idx + 1].level))
+	{
+	  errno = ENOTDIR;
+	  return -1;
+	}
+
+      ++idx;
+
+      s = endp + 1;
+      ++level;
+    }
+
+  errno = ENOENT;
+  return -1;
+}
diff --git a/posix/bug-glob2.c b/posix/tst-glob_memory.c
similarity index 76%
rename from posix/bug-glob2.c
rename to posix/tst-glob_memory.c
index 592d957..33961e8 100644
--- a/posix/bug-glob2.c
+++ b/posix/tst-glob_memory.c
@@ -27,18 +27,10 @@ 
 #include <string.h>
 #include <sys/stat.h>
 
-// #define DEBUG
-#ifdef DEBUG
-# define PRINTF(fmt, args...) \
-  do					\
-    {					\
-      int save_errno = errno;		\
-      printf (fmt, ##args);		\
-      errno = save_errno;		\
-    } while (0)
-#else
-# define PRINTF(fmt, args...)
-#endif
+#include <support/check.h>
+
+#include "tst-glob_common.c"
+
 
 #define LONG_NAME \
   "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
@@ -52,13 +44,7 @@ 
   "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
   "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
 
-static struct
-{
-  const char *name;
-  int level;
-  int type;
-  mode_t mode;
-} filesystem[] =
+struct filesystem_t filesystem[] =
 {
   { ".", 1, DT_DIR, 0755 },
   { "..", 1, DT_DIR, 0755 },
@@ -79,7 +65,7 @@  static struct
       { "..", 3, DT_DIR, 0755 },
       { "a", 3, DT_REG, 0644 }
 };
-#define nfiles (sizeof (filesystem) / sizeof (filesystem[0]))
+static const size_t nfiles = sizeof (filesystem) / sizeof (filesystem[0]);
 
 
 typedef struct
@@ -91,65 +77,10 @@  typedef struct
 } my_DIR;
 
 
-static long int
-find_file (const char *s)
-{
-  int level = 1;
-  long int idx = 0;
-
-  if (strcmp (s, ".") == 0)
-    return 0;
-
-  if (s[0] == '.' && s[1] == '/')
-    s += 2;
-
-  while (*s != '\0')
-    {
-      char *endp = strchrnul (s, '/');
-
-      PRINTF ("looking for %.*s, level %d\n", (int) (endp - s), s, level);
-
-      while (idx < nfiles && filesystem[idx].level >= level)
-	{
-	  if (filesystem[idx].level == level
-	      && memcmp (s, filesystem[idx].name, endp - s) == 0
-	      && filesystem[idx].name[endp - s] == '\0')
-	    break;
-	  ++idx;
-	}
-
-      if (idx == nfiles || filesystem[idx].level < level)
-	{
-	  errno = ENOENT;
-	  return -1;
-	}
-
-      if (*endp == '\0')
-	return idx + 1;
-
-      if (filesystem[idx].type != DT_DIR
-	  && (idx + 1 >= nfiles
-	      || filesystem[idx].level >= filesystem[idx + 1].level))
-	{
-	  errno = ENOTDIR;
-	  return -1;
-	}
-
-      ++idx;
-
-      s = endp + 1;
-      ++level;
-    }
-
-  errno = ENOENT;
-  return -1;
-}
-
-
 static void *
 my_opendir (const char *s)
 {
-  long int idx = find_file (s);
+  long int idx = find_file (s, filesystem, nfiles);
   my_DIR *dir;
 
   if (idx == -1)
@@ -241,7 +172,7 @@  my_closedir (void *dir)
 static int
 my_stat (const char *name, struct stat *st)
 {
-  long int idx = find_file (name);
+  long int idx = find_file (name, filesystem, nfiles);
 
   if (idx == -1)
     {
@@ -275,7 +206,7 @@  init_glob_altdirfuncs (glob_t *pglob)
 }
 
 
-int
+static int
 do_test (void)
 {
   mtrace ();
@@ -286,10 +217,7 @@  do_test (void)
 
   if (glob ("dir/*able/*", GLOB_ERR | GLOB_ALTDIRFUNC, NULL, &gl)
       != GLOB_ABORTED)
-    {
-      puts ("glob did not fail with GLOB_ABORTED");
-      exit (EXIT_FAILURE);
-    }
+    FAIL_EXIT1 ("glob did not fail with GLOB_ABORTED");
 
   globfree (&gl);
 
@@ -298,10 +226,7 @@  do_test (void)
 
   gl.gl_offs = 3;
   if (glob ("dir2/*", GLOB_DOOFFS, NULL, &gl) != GLOB_NOMATCH)
-    {
-      puts ("glob did not fail with GLOB_NOMATCH");
-      exit (EXIT_FAILURE);
-    }
+    FAIL_EXIT1 ("glot dit not fail with GLOB_NOMATCH");
 
   globfree (&gl);
 
@@ -310,5 +235,4 @@  do_test (void)
   return 0;
 }
 
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/posix/tst-gnuglob.c b/posix/tst-gnuglob.c
index d753674..f86eef7 100644
--- a/posix/tst-gnuglob.c
+++ b/posix/tst-gnuglob.c
@@ -20,7 +20,6 @@ 
 
 #include <dirent.h>
 #include <errno.h>
-#include <error.h>
 #include <glob.h>
 #include <mcheck.h>
 #include <stdio.h>
@@ -28,21 +27,11 @@ 
 #include <string.h>
 #include <sys/stat.h>
 
+#include <support/check.h>
 
-// #define DEBUG
-#ifdef DEBUG
-# define PRINTF(fmt, args...) printf (fmt, ##args)
-#else
-# define PRINTF(fmt, args...)
-#endif
-
+#include "tst-glob_common.c"
 
-static struct
-{
-  const char *name;
-  int level;
-  int type;
-} filesystem[] =
+struct filesystem_t filesystem[] =
 {
   { ".", 1, DT_DIR },
   { "..", 1, DT_DIR },
@@ -84,7 +73,7 @@  static struct
 	{ "..", 4, DT_DIR },
 	{ "hidden", 4, DT_REG }
 };
-#define nfiles (sizeof (filesystem) / sizeof (filesystem[0]))
+static const size_t nfiles = sizeof (filesystem) / sizeof (filesystem[0]);
 
 
 typedef struct
@@ -96,75 +85,10 @@  typedef struct
 } my_DIR;
 
 
-static long int
-find_file (const char *s)
-{
-  int level = 1;
-  long int idx = 0;
-
-  while (s[0] == '/')
-    {
-      if (s[1] == '\0')
-	{
-	  s = ".";
-	  break;
-	}
-      ++s;
-    }
-
-  if (strcmp (s, ".") == 0)
-    return 0;
-
-  if (s[0] == '.' && s[1] == '/')
-    s += 2;
-
-  while (*s != '\0')
-    {
-      char *endp = strchrnul (s, '/');
-
-      PRINTF ("looking for %.*s, level %d\n", (int) (endp - s), s, level);
-
-      while (idx < nfiles && filesystem[idx].level >= level)
-	{
-	  if (filesystem[idx].level == level
-	      && memcmp (s, filesystem[idx].name, endp - s) == 0
-	      && filesystem[idx].name[endp - s] == '\0')
-	    break;
-	  ++idx;
-	}
-
-      if (idx == nfiles || filesystem[idx].level < level)
-	{
-	  errno = ENOENT;
-	  return -1;
-	}
-
-      if (*endp == '\0')
-	return idx + 1;
-
-      if (filesystem[idx].type != DT_DIR
-	  && (idx + 1 >= nfiles
-	      || filesystem[idx].level >= filesystem[idx + 1].level))
-	{
-	  errno = ENOTDIR;
-	  return -1;
-	}
-
-      ++idx;
-
-      s = endp + 1;
-      ++level;
-    }
-
-  errno = ENOENT;
-  return -1;
-}
-
-
 static void *
 my_opendir (const char *s)
 {
-  long int idx = find_file (s);
+  long int idx = find_file (s, filesystem, nfiles);
   my_DIR *dir;
 
 
@@ -176,7 +100,7 @@  my_opendir (const char *s)
 
   dir = (my_DIR *) malloc (sizeof (my_DIR));
   if (dir == NULL)
-    error (EXIT_FAILURE, errno, "cannot allocate directory handle");
+    FAIL_EXIT1 ("cannot allocate directory handle");
 
   dir->level = filesystem[idx].level;
   dir->idx = idx;
@@ -247,13 +171,11 @@  my_closedir (void *dir)
 static int
 my_stat (const char *name, struct stat *st)
 {
-  long int idx = find_file (name);
+  long int idx = find_file (name, filesystem, nfiles);
 
   if (idx == -1)
-    {
-      PRINTF ("my_stat (\"%s\", ...) = -1 (%s)\n", name, strerror (errno));
-      return -1;
-    }
+    FAIL_EXIT1 ("%s (\"%s\", ...) == -1 (%s)", __func__, name,
+		strerror (errno));
 
   memset (st, '\0', sizeof (*st));
 
@@ -276,7 +198,8 @@  static const char *glob_errstring[] =
   [GLOB_ABORTED] = "read error",
   [GLOB_NOMATCH] = "no matches found"
 };
-#define nglob_errstring (sizeof (glob_errstring) / sizeof (glob_errstring[0]))
+static const size_t nglob_errstring = (sizeof (glob_errstring)
+				       / sizeof (glob_errstring[0]));
 
 
 static const char *
@@ -289,7 +212,7 @@  flagstr (int flags)
     "GLOB_ALTDIRFUNC", "GLOB_BRACE", "GLOB_NOMAGIC", "GLOB_TILDE",
     "GLOB_ONLYDIR", "GLOB_TILDECHECK"
   };
-#define nstrs (sizeof (strs) / sizeof (strs[0]))
+  static const size_t nstrs = (sizeof (strs) / sizeof (strs[0]));
   static char buf[100];
   char *cp = buf;
   int cnt;
@@ -311,7 +234,6 @@  flagstr (int flags)
     }
 
   return buf;
-#undef nstrs
 }
 
 
@@ -378,7 +300,6 @@  test_result (const char *fmt, int flags, glob_t *gl, const char *str[])
   return result;
 }
 
-
 static int
 do_test (void)
 {
@@ -416,7 +337,8 @@  do_test (void)
     result |= test_result (fmt, flags, &gl, (const char *[]) { c, NULL });    \
   else									      \
     printf ("result for glob (\"%s\", %s) = %s\n\n", fmt, flagstr (flags),    \
-	    errstr (errval))
+	    errstr (errval));						      \
+  globfree (&gl)
 
   test ("*/*/*", 0, 0,
 	"dir1lev1/dir2lev2/dir1lev3",
@@ -498,5 +420,4 @@  do_test (void)
   return result;
 }
 
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>