(root)/
coreutils-9.4/
gnulib-tests/
test-argmatch.c
       1  /* Test of exact or abbreviated match search.
       2     Copyright (C) 1990, 1998-1999, 2001-2023 Free Software Foundation, Inc.
       3  
       4     This program is free software: you can redistribute it and/or modify
       5     it under the terms of the GNU General Public License as published by
       6     the Free Software Foundation, either version 3 of the License, or
       7     (at your option) any later version.
       8  
       9     This program is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU General Public License for more details.
      13  
      14     You should have received a copy of the GNU General Public License
      15     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  /* Written by Bruno Haible <bruno@clisp.org>, 2007, based on test code
      18     by David MacKenzie <djm@gnu.ai.mit.edu>.  */
      19  
      20  #include <config.h>
      21  
      22  /* As of GCC 11.2.1, gcc -Wanalyzer-too-complex reports that main's
      23     use of CHECK macros expands to code that is too complicated for gcc
      24     -fanalyzer.  Suppress the resulting bogus warnings.  */
      25  #if 10 <= __GNUC__
      26  # pragma GCC diagnostic ignored "-Wanalyzer-null-argument"
      27  #endif
      28  
      29  #include "argmatch.h"
      30  
      31  #include <stdlib.h>
      32  
      33  #include "macros.h"
      34  
      35  # define N_(Msgid) (Msgid)
      36  
      37  /* Some packages define ARGMATCH_DIE and ARGMATCH_DIE_DECL in <config.h>, and
      38     thus must link with a definition of that function.  Provide it here.  */
      39  #ifdef ARGMATCH_DIE_DECL
      40  
      41  _Noreturn ARGMATCH_DIE_DECL;
      42  ARGMATCH_DIE_DECL { exit (1); }
      43  
      44  #endif
      45  
      46  enum backup_type
      47  {
      48    no_backups,
      49    simple_backups,
      50    numbered_existing_backups,
      51    numbered_backups
      52  };
      53  
      54  static const char *const backup_args[] =
      55  {
      56    "no", "none", "off",
      57    "simple", "never", "single",
      58    "existing", "nil", "numbered-existing",
      59    "numbered", "t", "newstyle",
      60    NULL
      61  };
      62  
      63  static const enum backup_type backup_vals[] =
      64  {
      65    no_backups, no_backups, no_backups,
      66    simple_backups, simple_backups, simple_backups,
      67    numbered_existing_backups, numbered_existing_backups, numbered_existing_backups,
      68    numbered_backups, numbered_backups, numbered_backups
      69  };
      70  
      71  ARGMATCH_DEFINE_GROUP(backup, enum backup_type)
      72  
      73  static const argmatch_backup_doc argmatch_backup_docs[] =
      74  {
      75    { "no",       N_("never make backups (even if --backup is given)") },
      76    { "numbered", N_("make numbered backups") },
      77    { "existing", N_("numbered if numbered backups exist, simple otherwise") },
      78    { "simple",   N_("always make simple backups") },
      79    { NULL, NULL }
      80  };
      81  
      82  static const argmatch_backup_arg argmatch_backup_args[] =
      83  {
      84    { "no",                no_backups },
      85    { "none",              no_backups },
      86    { "off",               no_backups },
      87    { "simple",            simple_backups },
      88    { "never",             simple_backups },
      89    { "single",            simple_backups },
      90    { "existing",          numbered_existing_backups },
      91    { "nil",               numbered_existing_backups },
      92    { "numbered-existing", numbered_existing_backups },
      93    { "numbered",          numbered_backups },
      94    { "t",                 numbered_backups },
      95    { "newstyle",          numbered_backups },
      96    { NULL, no_backups }
      97  };
      98  
      99  const argmatch_backup_group_type argmatch_backup_group =
     100  {
     101    argmatch_backup_args,
     102    argmatch_backup_docs,
     103    N_("\
     104  The backup suffix is '~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
     105  The version control method may be selected via the --backup option or through\n\
     106  the VERSION_CONTROL environment variable.  Here are the values:\n"),
     107    NULL
     108  };
     109  
     110  int
     111  main (int argc, char *argv[])
     112  {
     113  #define CHECK(Input, Output)                                            \
     114    do {                                                                  \
     115      ASSERT (ARGMATCH (Input, backup_args, backup_vals) == Output);      \
     116      ASSERT (argmatch_backup_choice (Input) == Output);                  \
     117      if (0 <= Output)                                                    \
     118        {                                                                 \
     119          enum backup_type val                                            \
     120            = argmatch_backup_args[Output < 0 ? 0 : Output].val;          \
     121          ASSERT (*argmatch_backup_value ("test", Input) == val);         \
     122          ASSERT (*argmatch_backup_value ("test",                         \
     123                                          argmatch_backup_argument (&val)) \
     124                  == val);                                                \
     125        }                                                                 \
     126    } while (0)
     127  
     128  #define CHECK_EXACT(Input, Output)                                      \
     129    do {                                                                  \
     130      ASSERT (ARGMATCH_EXACT (Input, backup_args) == Output);             \
     131    } while (0)
     132  
     133    /* Not found.  */
     134    CHECK ("klingon", -1);
     135    CHECK_EXACT ("klingon", -1);
     136  
     137    /* Exact match.  */
     138    CHECK ("none", 1);
     139    CHECK_EXACT ("none", 1);
     140    CHECK ("nil", 7);
     141    CHECK_EXACT ("nil", 7);
     142  
     143    /* Too long.  */
     144    CHECK ("nilpotent", -1);
     145    CHECK_EXACT ("nilpotent", -1);
     146  
     147    /* Abbreviated.  */
     148    CHECK ("simpl", 3);
     149    CHECK_EXACT ("simpl", -1);
     150    CHECK ("simp", 3);
     151    CHECK_EXACT ("simp", -1);
     152    CHECK ("sim", 3);
     153    CHECK_EXACT ("sim", -1);
     154  
     155    /* Exact match and abbreviated.  */
     156    CHECK ("numbered", 9);
     157    CHECK_EXACT ("numbered", 9);
     158    CHECK ("numbere", -2);
     159    CHECK_EXACT ("numbere", -1);
     160    CHECK ("number", -2);
     161    CHECK_EXACT ("number", -1);
     162    CHECK ("numbe", -2);
     163    CHECK_EXACT ("numbe", -1);
     164    CHECK ("numb", -2);
     165    CHECK_EXACT ("numb", -1);
     166    CHECK ("num", -2);
     167    CHECK_EXACT ("num", -1);
     168    CHECK ("nu", -2);
     169    CHECK_EXACT ("nu", -1);
     170    CHECK ("n", -2);
     171    CHECK_EXACT ("n", -1);
     172  
     173    /* Ambiguous abbreviated.  */
     174    CHECK ("ne", -2);
     175    CHECK_EXACT ("ne", -1);
     176  
     177    /* Ambiguous abbreviated, but same value ("single" and "simple").  */
     178    CHECK ("si", 3);
     179    CHECK_EXACT ("si", -1);
     180    CHECK ("s", 3);
     181    CHECK_EXACT ("s", -1);
     182  
     183  #undef CHECK
     184  #undef CHECK_EXACT
     185  
     186    argmatch_backup_usage (stdout);
     187  
     188    return 0;
     189  }