|
@@ -149,16 +149,29 @@ static struct argp_option names_options[] = {
|
|
|
{NULL}
|
|
|
};
|
|
|
|
|
|
-static bool
|
|
|
-is_file_selection_option (int key)
|
|
|
+static struct argp_option const *
|
|
|
+file_selection_option (int key)
|
|
|
{
|
|
|
struct argp_option *p;
|
|
|
|
|
|
for (p = names_options;
|
|
|
!(p->name == NULL && p->key == 0 && p->doc == NULL); p++)
|
|
|
if (p->key == key)
|
|
|
- return true;
|
|
|
- return false;
|
|
|
+ return p;
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+static char const *
|
|
|
+file_selection_option_name (int key)
|
|
|
+{
|
|
|
+ struct argp_option const *opt = file_selection_option (key);
|
|
|
+ return opt ? opt->name : NULL;
|
|
|
+}
|
|
|
+
|
|
|
+static bool
|
|
|
+is_file_selection_option (int key)
|
|
|
+{
|
|
|
+ return file_selection_option (key) != NULL;
|
|
|
}
|
|
|
|
|
|
/* Either NL or NUL, as decided by the --null option. */
|
|
@@ -670,7 +683,85 @@ name_list_adjust (void)
|
|
|
while (name_head->prev)
|
|
|
name_head = name_head->prev;
|
|
|
}
|
|
|
+
|
|
|
+/* For error-reporting purposes, keep a doubly-linked list of unconsumed file
|
|
|
+ selection options. The option is deemed unconsumed unless followed by one
|
|
|
+ or more file/member name arguments. When archive creation is requested,
|
|
|
+ each file selection option encountered is pushed into the list. The list
|
|
|
+ is cleared upon encountering a file name argument.
|
|
|
+
|
|
|
+ If the list is not empty when all arguments have been processed, an error
|
|
|
+ message is issued reporting the options that had no effect.
|
|
|
+
|
|
|
+ For simplicity, only a tail pointer of the list is maintained.
|
|
|
+*/
|
|
|
+
|
|
|
+struct name_elt *unconsumed_option_tail;
|
|
|
+
|
|
|
+/* Push an option to the list */
|
|
|
+static void
|
|
|
+unconsumed_option_push (struct name_elt *elt)
|
|
|
+{
|
|
|
+ elt->prev = unconsumed_option_tail;
|
|
|
+ if (unconsumed_option_tail)
|
|
|
+ unconsumed_option_tail->next = elt;
|
|
|
+ unconsumed_option_tail = elt;
|
|
|
+}
|
|
|
+
|
|
|
+/* Clear the unconsumed option list */
|
|
|
+static void
|
|
|
+unconsumed_option_free (void)
|
|
|
+{
|
|
|
+ while (unconsumed_option_tail)
|
|
|
+ {
|
|
|
+ struct name_elt *elt = unconsumed_option_tail;
|
|
|
+ unconsumed_option_tail = unconsumed_option_tail->prev;
|
|
|
+ free (elt);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* Report any options that have not been consumed */
|
|
|
+static void
|
|
|
+unconsumed_option_report (void)
|
|
|
+{
|
|
|
+ if (unconsumed_option_tail)
|
|
|
+ {
|
|
|
+ struct name_elt *elt;
|
|
|
+
|
|
|
+ ERROR ((0, 0, _("The following options were used after any non-optional arguments in archive create or update mode. These options are positional and affect only arguments that follow them. Please, rearrange them properly.")));
|
|
|
+
|
|
|
+ elt = unconsumed_option_tail;
|
|
|
+ while (elt->prev)
|
|
|
+ elt = elt->prev;
|
|
|
|
|
|
+ while (elt)
|
|
|
+ {
|
|
|
+ switch (elt->type)
|
|
|
+ {
|
|
|
+ case NELT_CHDIR:
|
|
|
+ ERROR ((0, 0, _("-C %s has no effect"), quote (elt->v.name)));
|
|
|
+ break;
|
|
|
+
|
|
|
+ case NELT_OPTION:
|
|
|
+ if (elt->v.opt.arg)
|
|
|
+ ERROR ((0, 0, _("--%s %s has no effect"),
|
|
|
+ file_selection_option_name (elt->v.opt.option),
|
|
|
+ quote (elt->v.opt.arg)));
|
|
|
+ else
|
|
|
+ ERROR ((0, 0, _("--%s has no effect"),
|
|
|
+ file_selection_option_name (elt->v.opt.option)));
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ elt = elt->next;
|
|
|
+ }
|
|
|
+
|
|
|
+ unconsumed_option_free ();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void
|
|
|
name_list_advance (void)
|
|
|
{
|
|
@@ -678,7 +769,18 @@ name_list_advance (void)
|
|
|
name_head = elt->next;
|
|
|
if (name_head)
|
|
|
name_head->prev = NULL;
|
|
|
- free (elt);
|
|
|
+ if (elt->type == NELT_OPTION || elt->type == NELT_CHDIR)
|
|
|
+ {
|
|
|
+ if (subcommand_option == CREATE_SUBCOMMAND
|
|
|
+ || subcommand_option == UPDATE_SUBCOMMAND)
|
|
|
+ unconsumed_option_push (elt);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (elt->type != NELT_NOOP)
|
|
|
+ unconsumed_option_free ();
|
|
|
+ free (elt);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1013,6 +1115,8 @@ name_next_elt (int change_dirs)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ unconsumed_option_report ();
|
|
|
+
|
|
|
return NULL;
|
|
|
}
|
|
|
|