Fix Savannah bug #35410: handle escape chars in filter/filter-out
authorPaul Smith <psmith@gnu.org>
Sat, 3 Mar 2012 22:12:46 +0000 (22:12 +0000)
committerPaul Smith <psmith@gnu.org>
Sat, 3 Mar 2012 22:12:46 +0000 (22:12 +0000)
Also add a valgrind suppression file for Guile-enabled make.

ChangeLog
function.c
tests/ChangeLog
tests/guile.supp [new file with mode: 0644]
tests/run_make_tests.pl
tests/scripts/functions/filter-out

index fdb2eb4..8c05546 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2012-03-03  Paul Smith  <psmith@gnu.org>
 
+       * function.c (func_filter_filterout): Recompute the length of each
+       filter word in case it was compressed due to escape chars.  Don't
+       reset the string as it's freed.  See Savannah bug #35410.
+
        * misc.c (collapse_continuations): Only use POSIX-style
        backslash/newline handling if the .POSIX target is set.
        Addresses Savannah bug #16670 without backward-incompatibility.
index 5acbb76..d68bc4d 100644 (file)
@@ -905,7 +905,6 @@ struct a_pattern
   char *str;
   char *percent;
   int length;
-  int save_c;
 };
 
 static char *
@@ -928,7 +927,9 @@ func_filter_filterout (char *o, char **argv, const char *funcname)
   char *p;
   unsigned int len;
 
-  /* Chop ARGV[0] up into patterns to match against the words.  */
+  /* Chop ARGV[0] up into patterns to match against the words.
+     We don't need to preserve it because our caller frees all the
+     argument memory anyway.  */
 
   pattail = &pathead;
   while ((p = find_next_token (&pat_iterator, &len)) != 0)
@@ -942,12 +943,13 @@ func_filter_filterout (char *o, char **argv, const char *funcname)
        ++pat_iterator;
 
       pat->str = p;
-      pat->length = len;
-      pat->save_c = p[len];
       p[len] = '\0';
       pat->percent = find_percent (p);
       if (pat->percent == 0)
        literals++;
+
+      /* find_percent() might shorten the string so LEN is wrong.  */
+      pat->length = strlen (pat->str);
     }
   *pattail = 0;
 
@@ -1029,9 +1031,6 @@ func_filter_filterout (char *o, char **argv, const char *funcname)
        --o;
     }
 
-  for (pp = pathead; pp != 0; pp = pp->next)
-    pp->str[pp->length] = pp->save_c;
-
   if (hashing)
     hash_free (&a_word_table, 0);
 
@@ -2377,7 +2376,7 @@ handle_function (char **op, const char **stringp)
   if (entry_p->expand_args)
     for (argvp=argv; *argvp != 0; ++argvp)
       free (*argvp);
-  if (abeg)
+  else if (abeg)
     free (abeg);
 
   return 1;
index 210dfb2..2c2284f 100644 (file)
@@ -1,5 +1,11 @@
 2012-03-03  Paul Smith  <psmith@gnu.org>
 
+       * scripts/functions/filter-out: Add filter tests and test escape
+       operations.  See Savannah bug #35410.
+
+       * guile.supp: Suppress valgrind errors from Guile
+       * run_make_tests.pl: Use the Guile suppression file.
+
        * scripts/misc/bs-nl: Check for POSIX and non-POSIX
        backslash/newline handling.  Addresses Savannah bug #16670.
 
diff --git a/tests/guile.supp b/tests/guile.supp
new file mode 100644 (file)
index 0000000..9e9b01b
--- /dev/null
@@ -0,0 +1,31 @@
+# Guile valgrind suppression file
+# Created with Guile 1.8.7
+
+# --- Garbage collection
+{
+  guilegc
+  Memcheck:Cond
+  ...
+  fun:scm_gc_for_newcell
+}
+{
+  guilegc
+  Memcheck:Value4
+  ...
+  fun:scm_gc_for_newcell
+}
+{
+  guilegc
+  Memcheck:Value8
+  ...
+  fun:scm_gc_for_newcell
+}
+
+
+# -- scm_alloc_struct
+{
+  guileheap
+  Memcheck:Leak
+  ...
+  fun:scm_alloc_struct
+}
index 33f4506..88f62a9 100755 (executable)
@@ -33,7 +33,7 @@
 
 $valgrind = 0;              # invoke make with valgrind
 $valgrind_args = '';
-$memcheck_args = '--num-callers=15 --tool=memcheck --leak-check=full';
+$memcheck_args = '--num-callers=15 --tool=memcheck --leak-check=full --suppressions=guile.supp';
 $massif_args = '--num-callers=15 --tool=massif --alloc-fn=xmalloc --alloc-fn=xcalloc --alloc-fn=xrealloc --alloc-fn=xstrdup --alloc-fn=xstrndup';
 $pure_log = undef;
 
index 6c8b27a..1fe4819 100644 (file)
@@ -1,6 +1,6 @@
 #                                                                    -*-perl-*-
 
-$description = "Test the filter-out function.";
+$description = "Test the filter and filter-out functions.";
 
 $details = "The makefile created in this test has two variables.  The
 filter-out function is first used to discard names ending in
@@ -11,18 +11,32 @@ which is only used if there are multiple literals present in both
 the pattern and text arguments.  The result of both filter-out
 functions is the same single .elc name.\n";
 
-open(MAKEFILE,"> $makefile");
+# Basic test -- filter
+run_make_test(q!
+files1 := $(filter %.o, foo.elc bar.o lose.o)
+files2 := $(filter %.o foo.i, foo.i bar.i lose.i foo.elc bar.o lose.o)
+all: ; @echo '$(files1) $(files2)'
+!,
+              '', "bar.o lose.o foo.i bar.o lose.o\n");
 
-print MAKEFILE <<'EOF';
+# Basic test -- filter-out
+run_make_test(q!
 files1 := $(filter-out %.o, foo.elc bar.o lose.o)
 files2 := $(filter-out foo.i bar.i lose.i %.o, foo.i bar.i lose.i foo.elc bar.o lose.o)
-all: ; @echo $(files1) $(files2)
-EOF
+all: ; @echo '$(files1) $(files2)'
+!,
+              '', "foo.elc foo.elc\n");
 
-close(MAKEFILE);
+# Escaped patterns
+run_make_test(q!all:;@echo '$(filter foo\%bar,foo%bar fooXbar)'!,
+              '', "foo%bar\n");
 
-&run_make_with_options($makefile, "", &get_logfile, 0);
-$answer = "foo.elc foo.elc\n";
-&compare_output($answer,&get_logfile(1));
+run_make_test(q!all:;@echo '$(filter foo\%\%\\\\\%\%bar,foo%%\\%%bar fooX\\Ybar)'!,
+              '', "foo%%\\%%bar\n");
+
+run_make_test(q!
+X = $(filter foo\\\\\%bar,foo\%bar foo\Xbar)
+all:;@echo '$(X)'!,
+              '', "foo\\%bar\n");
 
 1;