]> Dogcows Code - chaz/tar/commitdiff
Revamp initial name collection functions to ensure proper argument ordering.
authorSergey Poznyakoff <gray@gnu.org.ua>
Fri, 16 Aug 2013 19:54:40 +0000 (22:54 +0300)
committerSergey Poznyakoff <gray@gnu.org.ua>
Fri, 16 Aug 2013 20:03:35 +0000 (23:03 +0300)
* src/names.c (NELT_NOOP): New constant
(name_elt) <next,prev>: New members.
(name_array,allocated_entries,entries,scanned): Remove.
(check_name_alloc): Remove function.
(name_elt_alloc): New static.
(name_list_adjust,name_list_advance): New functions.
(name_add_name,name_add_dir)
(name_add_file): Use new allocation functions.
(read_next_name): Advance list head pointer as necessary
before returning.
(name_next_elt): Read elements from list.
* tests/T-cd.at: New file.
* tests/T-mult.at: New file.
* tests/T-nest.at: New file.
* tests/Makefile.am: Add new testcases.
* tests/testsuite.at: Likewise.

src/names.c
tests/Makefile.am
tests/T-cd.at [new file with mode: 0644]
tests/T-mult.at [new file with mode: 0644]
tests/T-nest.at [new file with mode: 0644]
tests/testsuite.at

index ccd016fa2a0c2a7ecc991ff156455878951317a5..94663d5bfe672ae785ce9bbd9e2a7bd37ad8b3a9 100644 (file)
@@ -197,7 +197,7 @@ static struct name *namelist;       /* first name in list, if any */
 static struct name *nametail;  /* end of name list */
 
 /* File name arguments are processed in two stages: first a
-   name_array (see below) is filled, then the names from it
+   name element list (see below) is filled, then the names from it
    are moved into the namelist.
 
    This awkward process is needed only to implement --same-order option,
@@ -207,21 +207,23 @@ static struct name *nametail;     /* end of name list */
 
    However, I very much doubt if we still need this -- Sergey */
 
-/* A name_array element contains entries of three types: */
+/* A name_list element contains entries of three types: */
 
 #define NELT_NAME  0   /* File name */
 #define NELT_CHDIR 1   /* Change directory request */
 #define NELT_FMASK 2   /* Change fnmatch options request */
 #define NELT_FILE  3   /* Read file names from that file */
-                        
+#define NELT_NOOP  4   /* No operation */
+
 struct name_elt        /* A name_array element. */
 {
+  struct name_elt *next, *prev;
   char type;           /* Element type, see NELT_* constants above */
   union
   {
     const char *name;  /* File or directory name */
     int matching_flags;/* fnmatch options if type == NELT_FMASK */
-    struct
+    struct             /* File, if type == NELT_FILE */
     {
       const char *name;/* File name */ 
       int term;        /* File name terminator in the list */
@@ -230,23 +232,47 @@ struct name_elt        /* A name_array element. */
   } v;
 };
 
-static struct name_elt *name_array;  /* store an array of names */
-static size_t allocated_entries; /* how big is the array? */
-static size_t entries;          /* how many entries does it have? */
-static size_t scanned;          /* how many of the entries have we scanned? */
-size_t name_count;              /* how many of the entries are names? */
+static struct name_elt *name_head;  /* store a list of names */
+size_t name_count;                 /* how many of the entries are names? */
 
-/* Check the size of name_array, reallocating it as necessary.  */
-static void
-check_name_alloc (void)
+static struct name_elt *
+name_elt_alloc (void)
 {
-  if (entries == allocated_entries)
+  struct name_elt *elt;
+
+  elt = xmalloc (sizeof (*elt));
+  if (!name_head)
     {
-      if (allocated_entries == 0)
-       allocated_entries = 10; /* Set initial allocation */
-      name_array = x2nrealloc (name_array, &allocated_entries,
-                              sizeof (name_array[0]));
+      name_head = elt;
+      name_head->prev = name_head->next = NULL;
+      name_head->type = NELT_NOOP;
+      elt = xmalloc (sizeof (*elt));
     }
+
+  elt->prev = name_head->prev;
+  if (name_head->prev)
+    name_head->prev->next = elt;
+  elt->next = name_head;
+  name_head->prev = elt;
+  return elt;
+}
+
+static void
+name_list_adjust (void)
+{
+  if (name_head)
+    while (name_head->prev)
+      name_head = name_head->prev;
+}
+
+static void
+name_list_advance (void)
+{
+  struct name_elt *elt = name_head;
+  name_head = elt->next;
+  if (name_head)
+    name_head->prev = NULL;
+  free (elt);
 }
 
 /* Add to name_array the file NAME with fnmatch options MATCHING_FLAGS */
@@ -254,17 +280,14 @@ void
 name_add_name (const char *name, int matching_flags)
 {
   static int prev_flags = 0; /* FIXME: Or EXCLUDE_ANCHORED? */
-  struct name_elt *ep;
+  struct name_elt *ep = name_elt_alloc ();
 
-  check_name_alloc ();
-  ep = &name_array[entries++];
   if (prev_flags != matching_flags)
     {
       ep->type = NELT_FMASK;
       ep->v.matching_flags = matching_flags;
       prev_flags = matching_flags;
-      check_name_alloc ();
-      ep = &name_array[entries++];
+      ep = name_elt_alloc ();
     }
   ep->type = NELT_NAME;
   ep->v.name = name;
@@ -275,9 +298,7 @@ name_add_name (const char *name, int matching_flags)
 void
 name_add_dir (const char *name)
 {
-  struct name_elt *ep;
-  check_name_alloc ();
-  ep = &name_array[entries++];
+  struct name_elt *ep = name_elt_alloc ();
   ep->type = NELT_CHDIR;
   ep->v.name = name;
 }
@@ -285,9 +306,7 @@ name_add_dir (const char *name)
 void
 name_add_file (const char *name, int term)
 {
-  struct name_elt *ep;
-  check_name_alloc ();
-  ep = &name_array[entries++];
+  struct name_elt *ep = name_elt_alloc ();
   ep->type = NELT_FILE;
   ep->v.file.name = name;
   ep->v.file.term = term;
@@ -306,13 +325,13 @@ name_init (void)
 {
   name_buffer = xmalloc (NAME_FIELD_SIZE + 2);
   name_buffer_length = NAME_FIELD_SIZE;
+  name_list_adjust ();
 }
 
 void
 name_term (void)
 {
   free (name_buffer);
-  free (name_array);
 }
 \f
 /* Prevent recursive inclusion of the same file */
@@ -427,7 +446,10 @@ read_next_name (struct name_elt *ent, struct name_elt *ret)
       else
        {
          if (add_file_id (ent->v.file.name))
-           return 1;
+           {
+             name_list_advance ();
+             return 1;
+           }
          if ((ent->v.file.fp = fopen (ent->v.file.name, "r")) == NULL)
            open_fatal (ent->v.file.name);
        }
@@ -448,7 +470,10 @@ read_next_name (struct name_elt *ent, struct name_elt *ret)
          /* fall through */
        case file_list_success:
          if (handle_option (name_buffer) == 0)
-           continue;
+           {
+             name_list_adjust ();
+             return 1;
+           }
          ret->type = NELT_NAME;
          ret->v.name = name_buffer;
          return 0;
@@ -457,6 +482,7 @@ read_next_name (struct name_elt *ent, struct name_elt *ret)
          if (strcmp (ent->v.file.name, "-"))
            fclose (ent->v.file.fp);
          ent->v.file.fp = NULL;
+         name_list_advance ();
          return 1;
        }
     }
@@ -507,43 +533,43 @@ static struct name_elt *
 name_next_elt (int change_dirs)
 {
   static struct name_elt entry;
+  struct name_elt *ep;
 
-  while (scanned != entries)
+  while ((ep = name_head) != NULL)
     {
-      struct name_elt *ep;
-
-      ep = &name_array[scanned];
-
       switch (ep->type)
        {
+       case NELT_NOOP:
+         name_list_advance ();
+         break;
+         
        case NELT_FMASK:
          matching_flags = ep->v.matching_flags;
-         ++scanned;
+         name_list_advance ();
          continue;
          
        case NELT_FILE:
          if (read_next_name (ep, &entry) == 0)
            return &entry;
-         ++scanned;
          continue;
              
        case NELT_CHDIR:
          if (change_dirs)
            {
-             ++scanned;
              copy_name (ep);
              if (chdir (name_buffer) < 0)
                chdir_fatal (name_buffer);
+             name_list_advance ();
              break;
            }
          /* fall trhough */
        case NELT_NAME:
-         ++scanned;
          copy_name (ep);
          if (unquote_option)
            unquote_string (name_buffer);
          entry.type = ep->type;
          entry.v.name = name_buffer;
+         name_list_advance ();
          return &entry;
        }
     }
index ab20552a96de93bdedf70a303350483da8f536a3..2783f9a4e4a737b1fbc284cf1a1012eb08a5fa70 100644 (file)
@@ -42,10 +42,13 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac
 ## ------------ ##
 
 TESTSUITE_AT = \
+ T-cd.at\
  T-empty.at\
  T-null.at\
  T-zfile.at\
  T-nonl.at\
+ T-mult.at\
+ T-nest.at\
  testsuite.at\
  append.at\
  append01.at\
diff --git a/tests/T-cd.at b/tests/T-cd.at
new file mode 100644 (file)
index 0000000..ac76021
--- /dev/null
@@ -0,0 +1,43 @@
+# Process this file with autom4te to create testsuite. -*- Autotest -*-
+#
+# Test suite for GNU tar.
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU tar.
+#
+# GNU tar 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.
+#
+# GNU tar 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/>.
+
+AT_SETUP([-C in file lists])
+AT_KEYWORDS([files-from T-cd])
+
+AT_TAR_CHECK([
+>file1
+mkdir dir
+>dir/file2
+>dir/file3
+AT_DATA([F1],[file1
+-C dir
+.
+])
+tar cf archive -T F1
+tar tf archive
+],
+[0],
+[file1
+./
+./file2
+./file3
+],[],[],[],[ustar])
+
+AT_CLEANUP
diff --git a/tests/T-mult.at b/tests/T-mult.at
new file mode 100644 (file)
index 0000000..d011b83
--- /dev/null
@@ -0,0 +1,46 @@
+# Process this file with autom4te to create testsuite. -*- Autotest -*-
+#
+# Test suite for GNU tar.
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU tar.
+#
+# GNU tar 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.
+#
+# GNU tar 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/>.
+
+AT_SETUP([multiple file lists])
+AT_KEYWORDS([files-from T-mult])
+
+AT_TAR_CHECK([
+>file1
+>file2
+>file3
+>file4
+AT_DATA([F1],[file1
+file2
+])
+AT_DATA([F2],[file3
+file4
+])
+tar cf archive -T F1 -T F2
+tar tf archive
+],
+[0],
+[file1
+file2
+file3
+file4
+],[],[],[],[ustar])
+
+AT_CLEANUP
+
diff --git a/tests/T-nest.at b/tests/T-nest.at
new file mode 100644 (file)
index 0000000..5c4b69d
--- /dev/null
@@ -0,0 +1,46 @@
+# Process this file with autom4te to create testsuite. -*- Autotest -*-
+#
+# Test suite for GNU tar.
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU tar.
+#
+# GNU tar 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.
+#
+# GNU tar 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/>.
+
+AT_SETUP([nested file lists])
+AT_KEYWORDS([files-from T-nest])
+
+AT_TAR_CHECK([
+>file1
+>file2
+>file3
+>file4
+AT_DATA([F1],[file1
+-T F2
+file2
+])
+AT_DATA([F2],[file3
+file4
+])
+tar cf archive -T F1
+tar tf archive
+],
+[0],
+[file1
+file3
+file4
+file2
+],[],[],[],[ustar])
+
+AT_CLEANUP
index 605cca3b367471fb50555520b8916e4c626a592e..5f7e4eaefe8bf2e03e1222ff1430d9af1f8fc7fc 100644 (file)
@@ -197,6 +197,9 @@ m4_include([opcomp05.at])
 m4_include([opcomp06.at])
 
 AT_BANNER([The -T option])
+m4_include([T-mult.at])
+m4_include([T-nest.at])
+m4_include([T-cd.at])
 m4_include([T-empty.at])
 m4_include([T-null.at])
 m4_include([T-zfile.at])
This page took 0.03553 seconds and 4 git commands to generate.