+/* File name arguments are processed in two stages: first a
+ 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,
+ which is meant to help process large archives on machines with
+ limited memory. With this option on, namelist contains at most one
+ entry, which diminishes the memory consumption.
+
+ However, I very much doubt if we still need this -- Sergey */
+
+/* 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 /* File, if type == NELT_FILE */
+ {
+ const char *name;/* File name */
+ int term; /* File name terminator in the list */
+ FILE *fp;
+ } file;
+ } v;
+};
+
+static struct name_elt *name_head; /* store a list of names */
+size_t name_count; /* how many of the entries are names? */
+
+static struct name_elt *
+name_elt_alloc (void)
+{
+ struct name_elt *elt;
+
+ elt = xmalloc (sizeof (*elt));
+ if (!name_head)
+ {
+ 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)