189 lines
5.8 KiB
C
189 lines
5.8 KiB
C
/* Test of exact or abbreviated match search.
|
|
Copyright (C) 1990, 1998-1999, 2001-2025 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 <https://www.gnu.org/licenses/>. */
|
|
|
|
/* Written by Bruno Haible <bruno@clisp.org>, 2007, based on test code
|
|
by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
|
|
|
#include <config.h>
|
|
|
|
/* As of GCC 11.2.1, gcc -Wanalyzer-too-complex reports that main's
|
|
use of CHECK macros expands to code that is too complicated for gcc
|
|
-fanalyzer. Suppress the resulting bogus warnings. */
|
|
#if _GL_GNUC_PREREQ (10, 0)
|
|
# pragma GCC diagnostic ignored "-Wanalyzer-null-argument"
|
|
#endif
|
|
|
|
#include "argmatch.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "macros.h"
|
|
|
|
# define N_(Msgid) (Msgid)
|
|
|
|
/* Some packages define ARGMATCH_DIE and ARGMATCH_DIE_DECL in <config.h>, and
|
|
thus must link with a definition of that function. Provide it here. */
|
|
#ifdef ARGMATCH_DIE_DECL
|
|
|
|
_Noreturn ARGMATCH_DIE_DECL;
|
|
ARGMATCH_DIE_DECL { exit (1); }
|
|
|
|
#endif
|
|
|
|
enum backup_type
|
|
{
|
|
no_backups,
|
|
simple_backups,
|
|
numbered_existing_backups,
|
|
numbered_backups
|
|
};
|
|
|
|
static const char *const backup_args[] =
|
|
{
|
|
"no", "none", "off",
|
|
"simple", "never", "single",
|
|
"existing", "nil", "numbered-existing",
|
|
"numbered", "t", "newstyle",
|
|
NULL
|
|
};
|
|
|
|
static const enum backup_type backup_vals[] =
|
|
{
|
|
no_backups, no_backups, no_backups,
|
|
simple_backups, simple_backups, simple_backups,
|
|
numbered_existing_backups, numbered_existing_backups, numbered_existing_backups,
|
|
numbered_backups, numbered_backups, numbered_backups
|
|
};
|
|
|
|
ARGMATCH_DEFINE_GROUP(backup, enum backup_type)
|
|
|
|
static const argmatch_backup_doc argmatch_backup_docs[] =
|
|
{
|
|
{ "no", N_("never make backups (even if --backup is given)") },
|
|
{ "numbered", N_("make numbered backups") },
|
|
{ "existing", N_("numbered if numbered backups exist, simple otherwise") },
|
|
{ "simple", N_("always make simple backups") },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
static const argmatch_backup_arg argmatch_backup_args[] =
|
|
{
|
|
{ "no", no_backups },
|
|
{ "none", no_backups },
|
|
{ "off", no_backups },
|
|
{ "simple", simple_backups },
|
|
{ "never", simple_backups },
|
|
{ "single", simple_backups },
|
|
{ "existing", numbered_existing_backups },
|
|
{ "nil", numbered_existing_backups },
|
|
{ "numbered-existing", numbered_existing_backups },
|
|
{ "numbered", numbered_backups },
|
|
{ "t", numbered_backups },
|
|
{ "newstyle", numbered_backups },
|
|
{ NULL, no_backups }
|
|
};
|
|
|
|
const argmatch_backup_group_type argmatch_backup_group =
|
|
{
|
|
argmatch_backup_args,
|
|
argmatch_backup_docs,
|
|
N_("\
|
|
The backup suffix is '~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
|
|
The version control method may be selected via the --backup option or through\n\
|
|
the VERSION_CONTROL environment variable. Here are the values:\n"),
|
|
NULL
|
|
};
|
|
|
|
int
|
|
main (int argc, char *argv[])
|
|
{
|
|
#define CHECK(Input, Output) \
|
|
do { \
|
|
ASSERT (ARGMATCH (Input, backup_args, backup_vals) == Output); \
|
|
ASSERT (argmatch_backup_choice (Input) == Output); \
|
|
if (0 <= Output) \
|
|
{ \
|
|
enum backup_type val \
|
|
= argmatch_backup_args[Output < 0 ? 0 : Output].val; \
|
|
ASSERT (*argmatch_backup_value ("test", Input) == val); \
|
|
ASSERT (*argmatch_backup_value ("test", \
|
|
argmatch_backup_argument (&val)) \
|
|
== val); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define CHECK_EXACT(Input, Output) \
|
|
do { \
|
|
ASSERT (ARGMATCH_EXACT (Input, backup_args) == Output); \
|
|
} while (0)
|
|
|
|
/* Not found. */
|
|
CHECK ("klingon", -1);
|
|
CHECK_EXACT ("klingon", -1);
|
|
|
|
/* Exact match. */
|
|
CHECK ("none", 1);
|
|
CHECK_EXACT ("none", 1);
|
|
CHECK ("nil", 7);
|
|
CHECK_EXACT ("nil", 7);
|
|
|
|
/* Too long. */
|
|
CHECK ("nilpotent", -1);
|
|
CHECK_EXACT ("nilpotent", -1);
|
|
|
|
/* Abbreviated. */
|
|
CHECK ("simpl", 3);
|
|
CHECK_EXACT ("simpl", -1);
|
|
CHECK ("simp", 3);
|
|
CHECK_EXACT ("simp", -1);
|
|
CHECK ("sim", 3);
|
|
CHECK_EXACT ("sim", -1);
|
|
|
|
/* Exact match and abbreviated. */
|
|
CHECK ("numbered", 9);
|
|
CHECK_EXACT ("numbered", 9);
|
|
CHECK ("numbere", -2);
|
|
CHECK_EXACT ("numbere", -1);
|
|
CHECK ("number", -2);
|
|
CHECK_EXACT ("number", -1);
|
|
CHECK ("numbe", -2);
|
|
CHECK_EXACT ("numbe", -1);
|
|
CHECK ("numb", -2);
|
|
CHECK_EXACT ("numb", -1);
|
|
CHECK ("num", -2);
|
|
CHECK_EXACT ("num", -1);
|
|
CHECK ("nu", -2);
|
|
CHECK_EXACT ("nu", -1);
|
|
CHECK ("n", -2);
|
|
CHECK_EXACT ("n", -1);
|
|
|
|
/* Ambiguous abbreviated. */
|
|
CHECK ("ne", -2);
|
|
CHECK_EXACT ("ne", -1);
|
|
|
|
/* Ambiguous abbreviated, but same value ("single" and "simple"). */
|
|
CHECK ("si", 3);
|
|
CHECK_EXACT ("si", -1);
|
|
CHECK ("s", 3);
|
|
CHECK_EXACT ("s", -1);
|
|
|
|
#undef CHECK
|
|
#undef CHECK_EXACT
|
|
|
|
argmatch_backup_usage (stdout);
|
|
|
|
return test_exit_status;
|
|
}
|