bug-grep
[Top][All Lists]
Advanced

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

FYI, [PATCH] use gnulib's regex code


From: Jim Meyering
Subject: FYI, [PATCH] use gnulib's regex code
Date: Thu, 04 Feb 2010 08:55:02 +0100

In addition to the just-posted patch,
      tests: exercise surprising -m1 vs. --context behavior

I'm about to push these:
      build: update gnulib submodule to latest
      maint: use regex from gnulib, rather than our bit-rotting one
      tests: adjust spencer #37 to pass with gnulib's regex code
      build: avoid warnings in gnulib-supplied regex files
      maint: adjust formatting in tests/Makefile.am
      maint: remove unused Makefile rule
      tests: use init.sh from gnulib

This series converts grep to use gnulib's regex (rather than grep's old,
unmaintained copy) when the libc one is found to be inadequate.
[Note, I've removed parts of the diffs below that merely showed
 lib/reg* being removed. ]


>From 74b28d9e9eb457581908d00d09701b6be5aa450a Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Wed, 3 Feb 2010 21:30:16 +0100
Subject: [PATCH 1/7] build: update gnulib submodule to latest

---
 gnulib |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/gnulib b/gnulib
index f1a7a8b..9d0ad65 160000
--- a/gnulib
+++ b/gnulib
@@ -1 +1 @@
-Subproject commit f1a7a8bf1da81d9b98ff8778a8651861eb84750d
+Subproject commit 9d0ad652de159d08e5f679842f8a2a5658196361
--
1.7.0.rc1.193.ge8618


>From 967f0d59b671a117e42740fffd036621954f0e55 Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Sat, 26 Dec 2009 11:45:36 +0100
Subject: [PATCH 2/7] maint: use regex from gnulib, rather than our bit-rotting 
one

* bootstrap.conf (gnulib_modules): Add regex.
* configure.ac: Don't use jm_INCLUDED_REGEX.
Update use of cache variable.
* lib/regex.c: Remove file.
* lib/regex.h: Likewise.
* m4/regex.m4: Likewise.
* POTFILES.in: Update to match.
---
 bootstrap.conf |    1 +
 configure.ac   |   12 +-
 lib/regex.c    | 7897 --------------------------------------------------------
 lib/regex.h    |  579 -----
 m4/regex.m4    |   74 -
 po/POTFILES.in |    2 +-
 6 files changed, 4 insertions(+), 8561 deletions(-)
 delete mode 100644 lib/regex.c
 delete mode 100644 lib/regex.h
 delete mode 100644 m4/regex.m4

diff --git a/bootstrap.conf b/bootstrap.conf
index 93711ea..4e846e5 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -53,6 +53,7 @@ obstack
 progname
 quotearg
 realloc
+regex
 ssize_t
 stddef
 stdlib
diff --git a/configure.ac b/configure.ac
index d9a11ac..1521f7e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -151,20 +151,12 @@ dnl I18N feature
 AM_GNU_GETTEXT_VERSION([0.17])
 AM_GNU_GETTEXT([external])

-dnl some folks ask for this, that's fine by me
-dnl hope they know what they're doing ...
-dnl if glibc2 regex is not included
-
-dnl Many GNU/Linux people have different
-dnl glibc versions with buggy regex.
-jm_INCLUDED_REGEX(lib/regex.c)
-
 dnl Some installers want to be informed if we do not use our regex.
 dnl For example, if the host platform uses dynamic linking and the installer
 dnl knows that the grep may be invoked on other hosts with buggy libraries,
 dnl then the installer should configure --with-included-regex.
-if test "$jm_with_regex" = no; then
-       AC_MSG_WARN(Included lib/regex.c not used)
+if test "$ac_use_included_regex" = no; then
+  AC_MSG_WARN([Included lib/regex.c not used])
 fi

 # support for pcre
diff --git a/lib/regex.c b/lib/regex.c
deleted file mode 100644
...
diff --git a/lib/regex.h b/lib/regex.h
deleted file mode 100644
...
diff --git a/m4/regex.m4 b/m4/regex.m4
deleted file mode 100644
...
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 8e98466..920413e 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -20,7 +20,7 @@ lib/error.c
 lib/getopt.c
 lib/obstack.c
 lib/quotearg.c
-lib/regex.c
+lib/regcomp.c
 lib/xalloc-die.c
 lib/xstrtol-error.c
 src/dfa.c
--
1.7.0.rc1.193.ge8618


>From 222bdcb32ecd45e6be7850515ef3fde0b682c88f Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Sat, 2 Jan 2010 18:43:22 +0100
Subject: [PATCH 3/7] tests: adjust spencer #37 to pass with gnulib's regex code

* tests/spencer1.tests: Change #37 to expect an exit status of 2, not 1.
grep 'a[b-a]' reports "Invalid range end".
---
 tests/spencer1.tests |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/tests/spencer1.tests b/tests/spencer1.tests
index e382d42..b1aa78b 100644
--- a/tests/spencer1.tests
+++ b/tests/spencer1.tests
@@ -34,7 +34,7 @@
 address@hidden@aac
 address@hidden@a-
 address@hidden@a-
address@hidden@-
address@hidden@-
 address@hidden@-
 address@hidden@-
 address@hidden@a]
--
1.7.0.rc1.193.ge8618


>From 26ad4e6d148f4d56ebb80417711c8a67082d43d7 Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Wed, 6 Jan 2010 12:06:14 +0100
Subject: [PATCH 4/7] build: avoid warnings in gnulib-supplied regex files

Now that we enable more warnings in lib/, we choose
to avoid some via patches applied by bootstrap, using
files in the gl/ hierarchy.  Other, less-important
warnings are avoided simply by turning off the
-Wold-style-definition option and using a slightly
relaxed set of warnings $(GNULIB_WARN_CFLAGS) in lib/.
* gl/lib/regcomp.c.diff: Avoid warnings.
* gl/lib/regex_internal.c.diff: Likewise.
* gl/lib/regex_internal.h.diff: Likewise.
* gl/lib/regexec.c.diff: Likewise.
* configure.ac (GNULIB_PORTCHECK): Disable only -Wold-style-definition.
* lib/Makefile.am (AM_CFLAGS): Use $(GNULIB_WARN_CFLAGS) rather
than the slightly more strict $(WARN_CFLAGS).
---
 configure.ac                 |    6 ++--
 gl/lib/regcomp.c.diff        |   63 ++++++++++++++++++++++++++++++++++++++++++
 gl/lib/regex_internal.c.diff |   25 ++++++++++++++++
 gl/lib/regex_internal.h.diff |   14 +++++++++
 gl/lib/regexec.c.diff        |   45 ++++++++++++++++++++++++++++++
 lib/Makefile.am              |    2 +-
 6 files changed, 151 insertions(+), 4 deletions(-)
 create mode 100644 gl/lib/regcomp.c.diff
 create mode 100644 gl/lib/regex_internal.c.diff
 create mode 100644 gl/lib/regex_internal.h.diff
 create mode 100644 gl/lib/regexec.c.diff

diff --git a/configure.ac b/configure.ac
index 1521f7e..5949f0e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -129,9 +129,9 @@ if test "$gl_gcc_warnings" = yes; then
   # We use a slightly smaller set of warning options for lib/.
   # Remove the following and save the result in GNULIB_WARN_CFLAGS.
   nw=
-  nw="$nw -Wuninitialized"
-  nw="$nw -Wunused-macros"
-  nw="$nw -Wmissing-prototypes"
+  #nw="$nw -Wuninitialized"
+  #nw="$nw -Wunused-macros"
+  #nw="$nw -Wmissing-prototypes"
   nw="$nw -Wold-style-definition"
   gl_MANYWARN_COMPLEMENT([GNULIB_WARN_CFLAGS], [$WARN_CFLAGS], [$nw])
   AC_SUBST([GNULIB_WARN_CFLAGS])
diff --git a/gl/lib/regcomp.c.diff b/gl/lib/regcomp.c.diff
new file mode 100644
index 0000000..63fc187
--- /dev/null
+++ b/gl/lib/regcomp.c.diff
@@ -0,0 +1,63 @@
+diff --git a/lib/regcomp.c b/lib/regcomp.c
+index d5968bd..4926676 100644
+--- a/lib/regcomp.c
++++ b/lib/regcomp.c
+@@ -541,7 +541,7 @@ regerror (errcode, preg, errbuf, errbuf_size)
+     size_t errbuf_size;
+ #else /* size_t might promote */
+ size_t
+-regerror (int errcode, const regex_t *_Restrict_ preg,
++regerror (int errcode, const regex_t *_Restrict_ preg _UNUSED_PARAMETER_,
+         char *_Restrict_ errbuf, size_t errbuf_size)
+ #endif
+ {
+@@ -1383,7 +1383,7 @@ calc_first (void *extra, bin_tree_t *node)
+
+ /* Pass 2: compute NEXT on the tree.  Preorder visit.  */
+ static reg_errcode_t
+-calc_next (void *extra, bin_tree_t *node)
++calc_next (void *extra _UNUSED_PARAMETER_, bin_tree_t *node)
+ {
+   switch (node->token.type)
+     {
+@@ -2744,7 +2744,8 @@ static reg_errcode_t
+ internal_function
+ build_collating_symbol (bitset_t sbcset,
+ # ifdef RE_ENABLE_I18N
+-                      re_charset_t *mbcset, Idx *coll_sym_alloc,
++                      re_charset_t *mbcset _UNUSED_PARAMETER_,
++                      Idx *coll_sym_alloc _UNUSED_PARAMETER_,
+ # endif
+                       const unsigned char *name)
+ {
+@@ -3323,7 +3324,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
+
+ static reg_errcode_t
+ parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp,
+-                     re_token_t *token, int token_len, re_dfa_t *dfa,
++                     re_token_t *token, int token_len,
++                     re_dfa_t *dfa _UNUSED_PARAMETER_,
+                      reg_syntax_t syntax, bool accept_hyphen)
+ {
+ #ifdef RE_ENABLE_I18N
+@@ -3410,8 +3412,9 @@ parse_bracket_symbol (bracket_elem_t *elem, re_string_t 
*regexp,
+
+ static reg_errcode_t
+ #ifdef RE_ENABLE_I18N
+-build_equiv_class (bitset_t sbcset, re_charset_t *mbcset,
+-                 Idx *equiv_class_alloc, const unsigned char *name)
++build_equiv_class (bitset_t sbcset, re_charset_t *mbcset _UNUSED_PARAMETER_,
++                 Idx *equiv_class_alloc _UNUSED_PARAMETER_,
++                 const unsigned char *name)
+ #else /* not RE_ENABLE_I18N */
+ build_equiv_class (bitset_t sbcset, const unsigned char *name)
+ #endif /* not RE_ENABLE_I18N */
+@@ -3816,7 +3819,7 @@ free_token (re_token_t *node)
+    and its children. */
+
+ static reg_errcode_t
+-free_tree (void *extra, bin_tree_t *node)
++free_tree (void *extra _UNUSED_PARAMETER_, bin_tree_t *node)
+ {
+   free_token (&node->token);
+   return REG_NOERROR;
diff --git a/gl/lib/regex_internal.c.diff b/gl/lib/regex_internal.c.diff
new file mode 100644
index 0000000..2cede3c
--- /dev/null
+++ b/gl/lib/regex_internal.c.diff
@@ -0,0 +1,25 @@
+diff --git a/lib/regex_internal.c b/lib/regex_internal.c
+index 904b88e..61c8d9d 100644
+--- a/lib/regex_internal.c
++++ b/lib/regex_internal.c
+@@ -18,6 +18,8 @@
+    with this program; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
++#include "verify.h"
++#include "intprops.h"
+ static void re_string_construct_common (const char *str, Idx len,
+                                       re_string_t *pstr,
+                                       RE_TRANSLATE_TYPE trans, bool icase,
+@@ -1390,7 +1392,10 @@ static void
+ internal_function
+ re_node_set_remove_at (re_node_set *set, Idx idx)
+ {
+-  if (idx < 0 || idx >= set->nelem)
++  verify (! TYPE_SIGNED (Idx));
++  /* if (idx < 0)
++     return; */
++  if (idx >= set->nelem)
+     return;
+   --set->nelem;
+   for (; idx < set->nelem; idx++)
diff --git a/gl/lib/regex_internal.h.diff b/gl/lib/regex_internal.h.diff
new file mode 100644
index 0000000..d1506a6
--- /dev/null
+++ b/gl/lib/regex_internal.h.diff
@@ -0,0 +1,14 @@
+diff --git i/lib/regex_internal.h w/lib/regex_internal.h
+index 859832f..3c7fe06 100644
+--- i/lib/regex_internal.h
++++ w/lib/regex_internal.h
+@@ -826,7 +826,8 @@ re_string_wchar_at (const re_string_t *pstr, Idx idx)
+
+ static int
+ internal_function __attribute ((pure))
+-re_string_elem_size_at (const re_string_t *pstr, Idx idx)
++re_string_elem_size_at (const re_string_t *pstr _UNUSED_PARAMETER_,
++                      Idx idx _UNUSED_PARAMETER_)
+ {
+ # ifdef _LIBC
+   const unsigned char *p, *extra;
diff --git a/gl/lib/regexec.c.diff b/gl/lib/regexec.c.diff
new file mode 100644
index 0000000..d9b6d1c
--- /dev/null
+++ b/gl/lib/regexec.c.diff
@@ -0,0 +1,45 @@
+diff --git a/lib/regexec.c b/lib/regexec.c
+index 21a8166..7762437 100644
+--- a/lib/regexec.c
++++ b/lib/regexec.c
+@@ -18,6 +18,8 @@
+    with this program; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
++#include "verify.h"
++#include "intprops.h"
+ static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
+                                    Idx n) internal_function;
+ static void match_ctx_clean (re_match_context_t *mctx) internal_function;
+@@ -378,8 +380,11 @@ re_search_2_stub (struct re_pattern_buffer *bufp,
+   Idx len = length1 + length2;
+   char *s = NULL;
+
+-  if (BE (length1 < 0 || length2 < 0 || stop < 0 || len < length1, 0))
+-    return -2;
++  verify (! TYPE_SIGNED (Idx));
++  if (BE (len < length1, 0))
++     return -2;
++  /* if (BE (length1 < 0 || length2 < 0 || stop < 0, 0))
++     return -2; */
+
+   /* Concatenate the strings.  */
+   if (length2 > 0)
+@@ -431,11 +436,14 @@ re_search_stub (struct re_pattern_buffer *bufp,
+   Idx last_start = start + range;
+
+   /* Check for out-of-range.  */
+-  if (BE (start < 0 || start > length, 0))
+-    return -1;
++  verify (! TYPE_SIGNED (Idx));
++  /* if (BE (start < 0, 0))
++     return -1; */
++  if (BE (start > length, 0))
++     return -1;
+   if (BE (length < last_start || (0 <= range && last_start < start), 0))
+     last_start = length;
+-  else if (BE (last_start < 0 || (range < 0 && start <= last_start), 0))
++  else if (BE (/* last_start < 0 || */ (range < 0 && start <= last_start), 0))
+     last_start = 0;
+
+   __libc_lock_lock (dfa->lock);
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 7b34222..c3760d6 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -18,7 +18,7 @@ include gnulib.mk

 INCLUDES = -I.. -I$(srcdir)

-AM_CFLAGS += $(WARN_CFLAGS) $(WERROR_CFLAGS)
+AM_CFLAGS += $(GNULIB_WARN_CFLAGS) $(WERROR_CFLAGS)

 libgreputils_a_SOURCES += \
   savedir.c savedir.h
--
1.7.0.rc1.193.ge8618


>From 1d8fbe1680e9e9570e21eb4264e0c6dac2c56fd4 Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Thu, 14 Jan 2010 08:07:15 +0100
Subject: [PATCH 5/7] maint: adjust formatting in tests/Makefile.am

* tests/Makefile.am (TESTS, CLEANFILES): Align and sort.
---
 tests/Makefile.am |   48 +++++++++++++++++++++++++++++++++++-------------
 1 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 470861e..14b25d7 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -14,20 +14,42 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.

-TESTS = warning.sh khadafy.sh spencer1.sh bre.sh ere.sh pcre.sh \
-        status.sh empty.sh options.sh backref.sh file.sh foad1.sh \
-        fmbtest.sh yesno.sh
-EXTRA_DIST = $(TESTS) \
-             khadafy.lines khadafy.regexp \
-             spencer1.awk spencer1.tests \
-             bre.awk ere.awk bre.tests ere.tests
-CLEANFILES = spencer1.script bre.script ere.script khadafy.out patfile \
-             cspatfile csinput yesno.txt
+TESTS =                \
+  backref.sh   \
+  bre.sh       \
+  empty.sh     \
+  ere.sh       \
+  file.sh      \
+  fmbtest.sh   \
+  foad1.sh     \
+  khadafy.sh   \
+  options.sh   \
+  pcre.sh      \
+  spencer1.sh  \
+  status.sh    \
+  warning.sh   \
+  yesno.sh
+
+EXTRA_DIST =   \
+  $(TESTS)     \
+  bre.awk      \
+  bre.tests    \
+  ere.awk      \
+  ere.tests    \
+  khadafy.lines        \
+  khadafy.regexp \
+  spencer1.awk \
+  spencer1.tests
+
+CLEANFILES = \
+  spencer1.script bre.script ere.script khadafy.out patfile \
+  cspatfile csinput yesno.txt
+
 TESTS_ENVIRONMENT = \
-       AWK=$(AWK) \
-       GREP=$(top_builddir)/src/grep \
-       GREP_OPTIONS='' \
-       LC_ALL=C
+  AWK=$(AWK) \
+  GREP=$(top_builddir)/src/grep \
+  GREP_OPTIONS='' \
+  LC_ALL=C

 # the *.sh when checkout does not have the right permission
 # make sure everyting is ok.
--
1.7.0.rc1.193.ge8618


>From 8580daf771fb9ca3376969b9b8581c29898aad9d Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Thu, 14 Jan 2010 08:08:01 +0100
Subject: [PATCH 6/7] maint: remove unused Makefile rule

* tests/Makefile.am (dist-hook): Remove rule.  No longer needed.
---
 tests/Makefile.am |    5 -----
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 14b25d7..097cf43 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -50,8 +50,3 @@ TESTS_ENVIRONMENT = \
   GREP=$(top_builddir)/src/grep \
   GREP_OPTIONS='' \
   LC_ALL=C
-
-# the *.sh when checkout does not have the right permission
-# make sure everyting is ok.
-dist-hook:
-       cd $(distdir); for i in $(TESTS); do chmod +x $$i; done
--
1.7.0.rc1.193.ge8618


>From bf543661d5291017d0b7eccd07cae7cc807a516d Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Sat, 16 Jan 2010 08:49:59 +0100
Subject: [PATCH 7/7] tests: use init.sh from gnulib

* tests/init.sh: New file, from gnulib.
* tests/Makefile.am (EXTRA_DIST): Add it.
(TESTS_ENVIRONMENT): Add variables and features.
(VERBOSE): Define.
---
 tests/Makefile.am |   46 +++++++++-
 tests/init.sh     |  255 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 296 insertions(+), 5 deletions(-)
 create mode 100644 tests/init.sh

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 097cf43..a76094a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -36,6 +36,7 @@ EXTRA_DIST =  \
   bre.tests    \
   ere.awk      \
   ere.tests    \
+  init.sh      \
   khadafy.lines        \
   khadafy.regexp \
   spencer1.awk \
@@ -45,8 +46,43 @@ CLEANFILES = \
   spencer1.script bre.script ere.script khadafy.out patfile \
   cspatfile csinput yesno.txt

-TESTS_ENVIRONMENT = \
-  AWK=$(AWK) \
-  GREP=$(top_builddir)/src/grep \
-  GREP_OPTIONS='' \
-  LC_ALL=C
+TESTS_ENVIRONMENT =                            \
+  tmp__=$$TMPDIR; test -d "$$tmp__" || tmp__=.;        \
+  TMPDIR=$$tmp__; export TMPDIR;               \
+  exec 9>&2;                                   \
+  shell_or_perl_() {                           \
+    if grep '^\#!/usr/bin/perl' "$$1" > /dev/null; then                        
\
+      if $(PERL) -e 'use warnings' > /dev/null 2>&1; then              \
+       grep '^\#!/usr/bin/perl -T' "$$1" > /dev/null && T_=T || T_=;   \
+        $(PERL) -w$$T_ -I$(srcdir) -MCoreutils                         \
+             -M"CuTmpdir qw($$f)" -- "$$1";    \
+      else                                     \
+       echo 1>&2 "$$tst: configure did not find a usable version of Perl," \
+         "so skipping this test";              \
+       (exit 77);                              \
+      fi;                                      \
+    else                                       \
+      $(SHELL) "$$1";                          \
+    fi;                                                \
+  };                                           \
+  export                                       \
+  AWK=$(AWK)                                   \
+  GREP=$(top_builddir)/src/grep                        \
+  GREP_OPTIONS=''                              \
+  LC_ALL=C                                     \
+  abs_top_builddir='$(abs_top_builddir)'       \
+  abs_top_srcdir='$(abs_top_srcdir)'           \
+  abs_srcdir='$(abs_srcdir)'                   \
+  srcdir='$(srcdir)'                           \
+  top_srcdir='$(top_srcdir)'                   \
+  CC='$(CC)'                                   \
+  MAKE=$(MAKE)                                 \
+  PACKAGE_BUGREPORT='$(PACKAGE_BUGREPORT)'     \
+  PACKAGE_VERSION=$(PACKAGE_VERSION)           \
+  PERL='$(PERL)'                               \
+  PREFERABLY_POSIX_SHELL='$(PREFERABLY_POSIX_SHELL)' \
+  REPLACE_GETCWD=$(REPLACE_GETCWD)             \
+  PATH='$(abs_top_builddir)$(PATH_SEPARATOR)'"$$PATH" \
+  ; shell_or_perl_
+
+VERBOSE = yes
diff --git a/tests/init.sh b/tests/init.sh
new file mode 100644
index 0000000..979eb3c
--- /dev/null
+++ b/tests/init.sh
@@ -0,0 +1,255 @@
+# source this file; set up for tests
+
+# Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program 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 General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Using this file in a test
+# =========================
+#
+# The typical skeleton of a test looks like this:
+#
+#   #!/bin/sh
+#   : ${srcdir=.}
+#   . "$srcdir/init.sh"; path_prepend_ .
+#   Execute some commands.
+#   Note that these commands are executed in a subdirectory, therefore you
+#   need to prepend "../" to relative filenames in the build directory.
+#   Set the exit code 0 for success, 77 for skipped, or 1 or other for failure.
+#   Use the skip_ and fail_ functions to print a diagnostic and then exit
+#   with the corresponding exit code.
+#   Exit $?
+
+# Executing a test that uses this file
+# ====================================
+#
+# Running a single test:
+#   $ make check TESTS=test-foo.sh
+#
+# Running a single test, with verbose output:
+#   $ make check TESTS=test-foo.sh VERBOSE=yes
+#
+# Running a single test, with single-stepping:
+#   1. Go into a sub-shell:
+#   $ bash
+#   2. Set relevant environment variables from TESTS_ENVIRONMENT in the
+#      Makefile:
+#   $ export srcdir=../../tests # this is an example
+#   3. Execute the commands from the test, copy&pasting them one by one:
+#   $ . "$srcdir/init.sh"; path_prepend_ .
+#   ...
+#   4. Finally
+#   $ exit
+
+# We use a trap below for cleanup.  This requires us to go through
+# hoops to get the right exit status transported through the handler.
+# So use `Exit STATUS' instead of `exit STATUS' inside of the tests.
+# Turn off errexit here so that we don't trip the bug with OSF1/Tru64
+# sh inside this function.
+Exit () { set +e; (exit $1); exit $1; }
+
+fail_() { echo "$ME_: failed test: $@" 1>&2; Exit 1; }
+skip_() { echo "$ME_: skipped test: $@" 1>&2; Exit 77; }
+
+# This is a stub function that is run upon trap (upon regular exit and
+# interrupt).  Override it with a per-test function, e.g., to unmount
+# a partition, or to undo any other global state changes.
+cleanup_() { :; }
+
+if ( diff --version < /dev/null 2>&1 | grep GNU ) 2>&1 > /dev/null; then
+  compare() { diff -u "$@"; }
+elif ( cmp --version < /dev/null 2>&1 | grep GNU ) 2>&1 > /dev/null; then
+  compare() { cmp -s "$@"; }
+else
+  compare() { cmp "$@"; }
+fi
+
+# An arbitrary prefix to help distinguish test directories.
+testdir_prefix_() { printf gt; }
+
+# Run the user-overridable cleanup_ function, remove the temporary
+# directory and exit with the incoming value of $?.
+remove_tmp_()
+{
+  __st=$?
+  cleanup_
+  # cd out of the directory we're about to remove
+  cd "$initial_cwd_" || cd / || cd /tmp
+  chmod -R u+rwx "$test_dir_"
+  # If removal fails and exit status was to be 0, then change it to 1.
+  rm -rf "$test_dir_" || { test $__st = 0 && __st=1; }
+  exit $__st
+}
+
+# Use this function to prepend to PATH an absolute name for each
+# specified, possibly-$initial_cwd_relative, directory.
+path_prepend_()
+{
+  while test $# != 0; do
+    path_dir_=$1
+    case $path_dir_ in
+      '') fail_ "invalid path dir: '$1'";;
+      /*) abs_path_dir_=$path_dir_;;
+      *) abs_path_dir_=`cd "$initial_cwd_/$path_dir_" && echo "$PWD"` \
+           || fail_ "invalid path dir: $path_dir_";;
+    esac
+    case $abs_path_dir_ in
+      *:*) fail_ "invalid path dir: '$abs_path_dir_'";;
+    esac
+    PATH="$abs_path_dir_:$PATH"
+    shift
+  done
+  export PATH
+}
+
+setup_()
+{
+  test "$VERBOSE" = yes && set -x
+
+  initial_cwd_=$PWD
+  ME_=`expr "./$0" : '.*/\(.*\)$'`
+
+  pfx_=`testdir_prefix_`
+  test_dir_=`mktempd_ "$initial_cwd_" "$pfx_-$ME_.XXXX"` \
+    || fail_ "failed to create temporary directory in $initial_cwd_"
+  cd "$test_dir_"
+
+  # This pair of trap statements ensures that the temporary directory,
+  # $test_dir_, is removed upon exit as well as upon catchable signal.
+  trap remove_tmp_ 0
+  trap 'Exit $?' 1 2 13 15
+}
+
+# Create a temporary directory, much like mktemp -d does.
+# Written by Jim Meyering.
+#
+# Usage: mktempd_ /tmp phoey.XXXXXXXXXX
+#
+# First, try to use the mktemp program.
+# Failing that, we'll roll our own mktemp-like function:
+#  - try to get random bytes from /dev/urandom
+#  - failing that, generate output from a combination of quickly-varying
+#      sources and gzip.  Ignore non-varying gzip header, and extract
+#      "random" bits from there.
+#  - given those bits, map to file-name bytes using tr, and try to create
+#      the desired directory.
+#  - make only $MAX_TRIES_ attempts
+
+# Helper function.  Print $N pseudo-random bytes from a-zA-Z0-9.
+rand_bytes_()
+{
+  n_=$1
+
+  # Maybe try openssl rand -base64 $n_prime_|tr '+/=\012' abcd first?
+  # But if they have openssl, they probably have mktemp, too.
+
+  chars_=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
+  dev_rand_=/dev/urandom
+  if test -r "$dev_rand_"; then
+    # Note: 256-length($chars_) == 194; 3 copies of $chars_ is 186 + 8 = 194.
+    dd ibs=$n_ count=1 if=$dev_rand_ 2>/dev/null \
+      | tr -c $chars_ 01234567$chars_$chars_$chars_
+    return
+  fi
+
+  n_plus_50_=`expr $n_ + 50`
+  cmds_='date; date +%N; free; who -a; w; ps auxww; ps ef; netstat -n'
+  data_=` (eval "$cmds_") 2>&1 | gzip `
+
+  # Ensure that $data_ has length at least 50+$n_
+  while :; do
+    len_=`echo "$data_"|wc -c`
+    test $n_plus_50_ -le $len_ && break;
+    data_=` (echo "$data_"; eval "$cmds_") 2>&1 | gzip `
+  done
+
+  echo "$data_" \
+    | dd bs=1 skip=50 count=$n_ 2>/dev/null \
+    | tr -c $chars_ 01234567$chars_$chars_$chars_
+}
+
+mktempd_()
+{
+  case $# in
+  2);;
+  *) fail_ "Usage: $ME DIR TEMPLATE";;
+  esac
+
+  destdir_=$1
+  template_=$2
+
+  MAX_TRIES_=4
+
+  # Disallow any trailing slash on specified destdir:
+  # it would subvert the post-mktemp "case"-based destdir test.
+  case $destdir_ in
+  /) ;;
+  */) fail_ "invalid destination dir: remove trailing slash(es)";;
+  esac
+
+  case $template_ in
+  *XXXX) ;;
+  *) fail_ "invalid template: $template_ (must have a suffix of at least 4 
X's)";;
+  esac
+
+  fail=0
+
+  # First, try to use mktemp.
+  d=`env -u TMPDIR mktemp -d -t -p "$destdir_" "$template_" 2>/dev/null` \
+    || fail=1
+
+  # The resulting name must be in the specified directory.
+  case $d in "$destdir_"*);; *) fail=1;; esac
+
+  # It must have created the directory.
+  test -d "$d" || fail=1
+
+  # It must have 0700 permissions.  Handle sticky "S" bits.
+  perms=`ls -dgo "$d" 2>/dev/null|tr S -` || fail=1
+  case $perms in drwx------*) ;; *) fail=1;; esac
+
+  test $fail = 0 && {
+    echo "$d"
+    return
+  }
+
+  # If we reach this point, we'll have to create a directory manually.
+
+  # Get a copy of the template without its suffix of X's.
+  base_template_=`echo "$template_"|sed 's/XX*$//'`
+
+  # Calculate how many X's we've just removed.
+  template_length_=`echo "$template_" | wc -c`
+  nx_=`echo "$base_template_" | wc -c`
+  nx_=`expr $template_length_ - $nx_`
+
+  err_=
+  i_=1
+  while :; do
+    X_=`rand_bytes_ $nx_`
+    candidate_dir_="$destdir_/$base_template_$X_"
+    err_=`mkdir -m 0700 "$candidate_dir_" 2>&1` \
+      && { echo "$candidate_dir_"; return; }
+    test $MAX_TRIES_ -le $i_ && break;
+    i_=`expr $i_ + 1`
+  done
+  fail_ "$err_"
+}
+
+# If you want to override the testdir_prefix_ function,
+# or to add more utility functions, use this file.
+test -f "$srcdir/init.cfg" \
+  && . "$srcdir/init.cfg"
+
+setup_ "$@"
--
1.7.0.rc1.193.ge8618




reply via email to

[Prev in Thread] Current Thread [Next in Thread]