Avoid macro preprocessing when filling the parse_table for better
readability.

* find/parser.c (PASTE, PARSE_OPTION, PARSE_POSOPT, PARSE_TEST,
PARSE_TEST_NP, PARSE_ACTION, PARSE_PUNCTUATION): Remove macros.
(parse_table): Replace macro-based filling with regular structure entries.
Group entries by types: regular options, positional options, punctuation,
tests and actions; loosely sort within each group.
Remove duplicate "atime" entry introduced in commit 7102a229fa.
While at it, change -help and -version from ARG_TEST to ARG_OPTION.
---
 find/parser.c | 221 +++++++++++++++++++++++---------------------------
 1 file changed, 102 insertions(+), 119 deletions(-)

diff --git a/find/parser.c b/find/parser.c
index f4b38d4c..03000645 100644
--- a/find/parser.c
+++ b/find/parser.c
@@ -191,28 +191,6 @@ static bool stream_is_tty(FILE *fp);
 static bool parse_noop (const struct parser_table* entry,
                         char **argv, int *arg_ptr);
 
-#define PASTE(x,y) x##y
-
-
-#define PARSE_OPTION(what,suffix) \
-  { (ARG_OPTION), (what), PASTE(parse_,suffix), nullptr }
-
-#define PARSE_POSOPT(what,suffix) \
-  { (ARG_POSITIONAL_OPTION), (what), PASTE(parse_,suffix), nullptr }
-
-#define PARSE_TEST(what,suffix) \
-  { (ARG_TEST), (what), PASTE(parse_,suffix), PASTE(pred_,suffix) }
-
-#define PARSE_TEST_NP(what,suffix) \
-  { (ARG_TEST), (what), PASTE(parse_,suffix), nullptr }
-
-#define PARSE_ACTION(what,suffix) \
-  { (ARG_ACTION), (what), PASTE(parse_,suffix), PASTE(pred_,suffix) }
-
-#define PARSE_PUNCTUATION(what,suffix) \
-  { (ARG_PUNCTUATION), (what), PASTE(parse_,suffix), PASTE(pred_,suffix) }
-
-
 /* Predicates we cannot handle in the usual way.  If you add an entry
  * to this table, double-check the switch statement in
  * pred_sanity_check() to make sure that the new case is being
@@ -223,113 +201,118 @@ static struct parser_table const parse_entry_newerXY =
     ARG_SPECIAL_PARSE, "newerXY",            parse_newerXY, pred_newerXY /* 
BSD  */
   };
 
-/* GNU find predicates that are not mentioned in POSIX.2 are marked `GNU'.
+/* GNU find predicates that are not mentioned in POSIX are marked `GNU'.
    If they are in some Unix versions of find, they are marked `Unix'. */
 
 static struct parser_table const parse_table[] =
 {
-  PARSE_PUNCTUATION("!",                     negate), /* POSIX */
-  PARSE_PUNCTUATION("not",                   negate),        /* GNU */
-  PARSE_PUNCTUATION("(",                     openparen), /* POSIX */
-  PARSE_PUNCTUATION(")",                     closeparen), /* POSIX */
-  PARSE_PUNCTUATION(",",                     comma),         /* GNU */
-  PARSE_PUNCTUATION("a",                     and), /* POSIX */
-  PARSE_TEST       ("amin",                  amin),          /* GNU */
-  PARSE_PUNCTUATION("and",                   and),              /* GNU */
-  PARSE_TEST       ("anewer",                anewer),        /* GNU */
-  {ARG_TEST,       "atime",                  parse_time, pred_atime}, /* POSIX 
*/
-  PARSE_TEST       ("cmin",                  cmin),          /* GNU */
-  PARSE_TEST       ("cnewer",                cnewer),        /* GNU */
-  {ARG_TEST,       "ctime",                  parse_time, pred_ctime}, /* POSIX 
*/
-  PARSE_TEST       ("context",               context),      /* GNU */
-  PARSE_POSOPT     ("daystart",              daystart),      /* GNU */
-  PARSE_ACTION     ("delete",                delete), /* GNU, Mac OS, FreeBSD 
*/
-  PARSE_OPTION     ("d",                     d), /* Mac OS X, FreeBSD, NetBSD, 
OpenBSD, but deprecated  in favour of -depth */
-  PARSE_OPTION     ("depth",                 depth), /* POSIX */
-  PARSE_TEST       ("empty",                 empty),         /* GNU */
-  {ARG_ACTION,      "exec",    parse_exec, pred_exec}, /* POSIX */
-  {ARG_TEST,        "executable",            parse_accesscheck, 
pred_executable}, /* GNU, 4.3.0+ */
-  PARSE_ACTION     ("execdir",               execdir), /* *BSD, GNU */
-  PARSE_OPTION     ("files0-from",           files0_from),   /* GNU */
-  PARSE_ACTION     ("fls",                   fls),           /* GNU */
-  PARSE_POSOPT     ("follow",                follow),  /* GNU, Unix */
-  PARSE_ACTION     ("fprint",                fprint),        /* GNU */
-  PARSE_ACTION     ("fprint0",               fprint0),       /* GNU */
-  {ARG_ACTION,      "fprintf", parse_fprintf, pred_fprintf}, /* GNU */
-  PARSE_TEST       ("fstype",                fstype),  /* GNU, Unix */
-  PARSE_TEST       ("gid",                   gid),           /* GNU */
-  PARSE_TEST       ("group",                 group), /* POSIX */
-  PARSE_OPTION     ("ignore_readdir_race",   ignore_race),   /* GNU */
-  PARSE_TEST       ("ilname",                ilname),        /* GNU */
-  PARSE_TEST       ("iname",                 iname),         /* GNU */
-  PARSE_TEST       ("inum",                  inum),    /* GNU, Unix */
-  PARSE_TEST       ("ipath",                 ipath), /* GNU, deprecated in 
favour of iwholename */
-  PARSE_TEST_NP    ("iregex",                iregex),        /* GNU */
-  PARSE_TEST_NP    ("iwholename",            iwholename),    /* GNU */
-  PARSE_TEST       ("links",                 links), /* POSIX */
-  PARSE_TEST       ("lname",                 lname),         /* GNU */
-  PARSE_ACTION     ("ls",                    ls),      /* GNU, Unix */
-  PARSE_OPTION     ("maxdepth",              maxdepth),      /* GNU */
-  PARSE_OPTION     ("mindepth",              mindepth),      /* GNU */
-  PARSE_TEST       ("mmin",                  mmin),          /* GNU */
-  PARSE_OPTION     ("mount",                 xdev),         /* Unix */
-  {ARG_TEST,       "mtime",                  parse_time, pred_mtime}, /* POSIX 
*/
-  PARSE_TEST       ("name",                  name),
-#ifdef UNIMPLEMENTED_UNIX
-  PARSE(ARG_UNIMPLEMENTED, "ncpio",          ncpio),        /* Unix */
-#endif
-  PARSE_TEST       ("newer",                 newer), /* POSIX */
-  {ARG_TEST,       "atime",                  parse_time, pred_atime}, /* POSIX 
*/
-  PARSE_OPTION     ("noleaf",                noleaf),        /* GNU */
-  PARSE_TEST       ("nogroup",               nogroup), /* POSIX */
-  PARSE_TEST       ("nouser",                nouser), /* POSIX */
-  PARSE_OPTION     ("noignore_readdir_race", noignore_race), /* GNU */
-  PARSE_POSOPT     ("nowarn",                nowarn),        /* GNU */
-  PARSE_POSOPT     ("warn",                  warn),          /* GNU */
-  PARSE_PUNCTUATION("o",                     or), /* POSIX */
-  PARSE_PUNCTUATION("or",                    or),            /* GNU */
-  PARSE_ACTION     ("ok",                    ok), /* POSIX */
-  PARSE_ACTION     ("okdir",                 okdir), /* GNU (-execdir is BSD) 
*/
-  PARSE_TEST       ("path",                  path), /* POSIX */
-  PARSE_TEST       ("perm",                  perm), /* POSIX */
-  PARSE_ACTION     ("print",                 print), /* POSIX */
-  PARSE_ACTION     ("print0",                print0),        /* GNU */
-  {ARG_ACTION,      "printf",   parse_printf, nullptr},      /* GNU */
-  PARSE_ACTION     ("prune",                 prune), /* POSIX */
-  PARSE_ACTION     ("quit",                  quit),          /* GNU */
-  {ARG_TEST,       "readable",            parse_accesscheck, pred_readable}, 
/* GNU, 4.3.0+ */
-  PARSE_TEST       ("regex",                 regex),         /* GNU */
-  PARSE_POSOPT     ("regextype",             regextype),     /* GNU */
-  PARSE_TEST       ("samefile",              samefile),      /* GNU */
-  PARSE_TEST       ("size",                  size), /* POSIX */
-  PARSE_TEST       ("type",                  type), /* POSIX */
-  PARSE_TEST       ("uid",                   uid),           /* GNU */
-  PARSE_TEST       ("used",                  used),          /* GNU */
-  PARSE_TEST       ("user",                  user), /* POSIX */
-  PARSE_TEST_NP    ("wholename",             wholename), /* GNU, replaced 
-path, but now -path is standardized since POSIX 2008 */
-  {ARG_TEST,       "writable",               parse_accesscheck, 
pred_writable}, /* GNU, 4.3.0+ */
-  PARSE_OPTION     ("xdev",                  xdev), /* POSIX */
-  PARSE_TEST       ("xtype",                 xtype),         /* GNU */
+  /* Regular options: no PRED function.  */
+  { ARG_OPTION, "d",                     parse_d,             nullptr }, /* 
Mac OS X, FreeBSD, NetBSD, OpenBSD */
+                                                                         /* 
but deprecated in favour of -depth */
+  { ARG_OPTION, "depth",                 parse_depth,         nullptr }, /* 
POSIX */
+  { ARG_OPTION, "files0-from",           parse_files0_from,   nullptr }, /* 
GNU */
+  { ARG_OPTION, "ignore_readdir_race",   parse_ignore_race,   nullptr }, /* 
GNU */
+  { ARG_OPTION, "maxdepth",              parse_maxdepth,      nullptr }, /* 
GNU */
+  { ARG_OPTION, "mindepth",              parse_mindepth,      nullptr }, /* 
GNU */
+  { ARG_OPTION, "mount",                 parse_xdev,          nullptr }, /* 
Unix */
+  { ARG_OPTION, "noleaf",                parse_noleaf,        nullptr }, /* 
GNU */
+  { ARG_OPTION, "noignore_readdir_race", parse_noignore_race, nullptr }, /* 
GNU */
+  { ARG_OPTION, "xdev",                  parse_xdev,          nullptr }, /* 
POSIX */
+  /* GNU mandated, general options.  */
+  { ARG_OPTION, "help",                  parse_help,          nullptr }, /* 
GNU */
+  { ARG_OPTION, "-help",                 parse_help,          nullptr }, /* 
GNU */
+  { ARG_OPTION, "version",               parse_version,       nullptr }, /* 
GNU */
+  { ARG_OPTION, "-version",              parse_version,       nullptr }, /* 
GNU */
+
+  /* Positional options (whose position is important).  */
+  { ARG_POSITIONAL_OPTION, "daystart",   parse_daystart,  nullptr }, /* GNU */
+  { ARG_POSITIONAL_OPTION, "follow",     parse_follow,    nullptr }, /* GNU, 
Unix */
+  { ARG_POSITIONAL_OPTION, "nowarn",     parse_nowarn,    nullptr }, /* GNU */
+  { ARG_POSITIONAL_OPTION, "regextype",  parse_regextype, nullptr }, /* GNU */
+  { ARG_POSITIONAL_OPTION, "warn",       parse_warn,      nullptr }, /* GNU */
+
+  /* Punctuation. */
+  { ARG_PUNCTUATION, "!",   parse_negate,     pred_negate     }, /* POSIX */
+  { ARG_PUNCTUATION, "not", parse_negate,     pred_negate     }, /* GNU */
+  { ARG_PUNCTUATION, "(",   parse_openparen,  pred_openparen  }, /* POSIX */
+  { ARG_PUNCTUATION, ")",   parse_closeparen, pred_closeparen }, /* POSIX */
+  { ARG_PUNCTUATION, ",",   parse_comma,      pred_comma      }, /* GNU */
+  { ARG_PUNCTUATION, "a",   parse_and,        pred_and        }, /* POSIX */
+  { ARG_PUNCTUATION, "and", parse_and,        pred_and        }, /* GNU */
+  { ARG_PUNCTUATION, "o",   parse_or,         pred_or         }, /* POSIX */
+  { ARG_PUNCTUATION, "or",  parse_or,         pred_or         }, /* GNU */
+
+  /* Tests.  */
+  { ARG_TEST, "amin",        parse_amin,        pred_amin       }, /* GNU */
+  { ARG_TEST, "anewer",      parse_anewer,      pred_anewer     }, /* GNU */
+  { ARG_TEST, "atime",       parse_time,        pred_atime      }, /* POSIX */
+  { ARG_TEST, "cmin",        parse_cmin,        pred_cmin       }, /* GNU */
+  { ARG_TEST, "cnewer",      parse_cnewer,      pred_cnewer     }, /* GNU */
+  { ARG_TEST, "ctime",       parse_time,        pred_ctime      }, /* POSIX */
+  { ARG_TEST, "context",     parse_context,     pred_context    }, /* GNU */
+  { ARG_TEST, "empty",       parse_empty,       pred_empty      }, /* GNU */
+  { ARG_TEST, "executable",  parse_accesscheck, pred_executable }, /* GNU, 
4.3.0+ */
+  { ARG_TEST, "false",       parse_false,       pred_false      }, /* GNU */
+  { ARG_TEST, "fstype",      parse_fstype,      pred_fstype     }, /* GNU, 
Unix */
+  { ARG_TEST, "gid",         parse_gid,         pred_gid        }, /* GNU */
+  { ARG_TEST, "group",       parse_group,       pred_group      }, /* POSIX */
+  { ARG_TEST, "ilname",      parse_ilname,      pred_ilname     }, /* GNU */
+  { ARG_TEST, "iname",       parse_iname,       pred_iname      }, /* GNU */
+  { ARG_TEST, "inum",        parse_inum,        pred_inum       }, /* GNU, 
Unix */
+  { ARG_TEST, "ipath",       parse_ipath,       pred_ipath      }, /* GNU */
+  { ARG_TEST, "iregex",      parse_iregex,      pred_regex      }, /* GNU */
+  { ARG_TEST, "iwholename",  parse_iwholename,  pred_ipath      }, /* GNU */
+  { ARG_TEST, "links",       parse_links,       pred_links      }, /* POSIX */
+  { ARG_TEST, "lname",       parse_lname,       pred_lname      }, /* GNU */
+  { ARG_TEST, "mmin",        parse_mmin,        pred_mmin       }, /* GNU */
+  { ARG_TEST, "mtime",       parse_time,        pred_mtime      }, /* POSIX */
+  { ARG_TEST, "name",        parse_name,        pred_name       }, /* POSIX */
+  { ARG_TEST, "newer",       parse_newer,       pred_newer      }, /* POSIX */
+  { ARG_TEST, "nogroup",     parse_nogroup,     pred_nogroup    }, /* POSIX */
+  { ARG_TEST, "nouser",      parse_nouser,      pred_nouser     }, /* POSIX */
+  { ARG_TEST, "path",        parse_path,        pred_path       }, /* POSIX */
+  { ARG_TEST, "perm",        parse_perm,        pred_perm       }, /* POSIX */
+  { ARG_TEST, "readable",    parse_accesscheck, pred_readable   }, /* GNU, 
4.3.0+ */
+  { ARG_TEST, "regex",       parse_regex,       pred_regex      }, /* GNU */
+  { ARG_TEST, "samefile",    parse_samefile,    pred_samefile   }, /* GNU */
+  { ARG_TEST, "size",        parse_size,        pred_size       }, /* POSIX */
+  { ARG_TEST, "true",        parse_true,        pred_true       }, /* GNU */
+  { ARG_TEST, "type",        parse_type,        pred_type       }, /* POSIX */
+  { ARG_TEST, "uid",         parse_uid,         pred_uid        }, /* GNU */
+  { ARG_TEST, "used",        parse_used,        pred_used       }, /* GNU */
+  { ARG_TEST, "user",        parse_user,        pred_user       }, /* POSIX */
+  { ARG_TEST, "wholename",   parse_wholename,   pred_path       }, /* GNU, 
replaced -path, but now -path is standardized since POSIX 2008 */
+  { ARG_TEST, "writable",    parse_accesscheck, pred_writable   }, /* GNU, 
4.3.0+ */
+  { ARG_TEST, "xtype",       parse_xtype,       pred_xtype      }, /* GNU */
+
+  /* Actions.  */
+  { ARG_ACTION, "delete",    parse_delete,      pred_delete  }, /* GNU, Mac 
OS, FreeBSD */
+  { ARG_ACTION, "exec",      parse_exec,        pred_exec    }, /* POSIX */
+  { ARG_ACTION, "execdir",   parse_execdir,     pred_execdir }, /* *BSD, GNU */
+  { ARG_ACTION, "fls",       parse_fls,         pred_fls     }, /* GNU */
+  { ARG_ACTION, "fprint",    parse_fprint,      pred_fprint  }, /* GNU */
+  { ARG_ACTION, "fprint0",   parse_fprint0,     pred_fprint0 }, /* GNU */
+  { ARG_ACTION, "fprintf",   parse_fprintf,     pred_fprintf }, /* GNU */
+  { ARG_ACTION, "ls",        parse_ls,          pred_ls      }, /* GNU, Unix */
+  { ARG_ACTION, "ok",        parse_ok,          pred_ok      }, /* POSIX */
+  { ARG_ACTION, "okdir",     parse_okdir,       pred_okdir   }, /* GNU 
(-execdir is BSD) */
+  { ARG_ACTION, "print",     parse_print,       pred_print   }, /* POSIX */
+  { ARG_ACTION, "print0",    parse_print0,      pred_print0  }, /* GNU */
+  { ARG_ACTION, "printf",    parse_printf,      pred_fprintf }, /* GNU */
+  { ARG_ACTION, "prune",     parse_prune,       pred_prune   }, /* POSIX */
+  { ARG_ACTION, "quit",      parse_quit,        pred_quit    }, /* GNU */
+
 #ifdef UNIMPLEMENTED_UNIX
   /* It's pretty ugly for find to know about archive formats.
-     Plus what it could do with cpio archives is very limited.
+     Plus what it could do with cpio/ncpio archives is very limited.
      Better to leave it out.  */
-  PARSE(ARG_UNIMPLEMENTED,      "cpio",                  cpio), /* Unix */
+  "ncpio", /* Unix */
+  "cpio",  /* Unix */
 #endif
-  /* gnulib's stdbool.h might have made true and false into macros,
-   * so we can't leave naked 'true' and 'false' tokens, so we have
-   * to expand the relevant entries longhand.
-   */
-  {ARG_TEST, "false",                 parse_false,   pred_false}, /* GNU */
-  {ARG_TEST, "true",                  parse_true,    pred_true }, /* GNU */
+
   /* Internal pseudo-option, therefore 3 minus: ---noop.  */
-  {ARG_NOOP, "--noop",                nullptr,       pred_true }, /* GNU, 
internal use only */
+  { ARG_NOOP, "--noop", nullptr, pred_true }, /* GNU, internal use only */
 
-  /* Various other cases that don't fit neatly into our macro scheme. */
-  {ARG_TEST, "help",                  parse_help,    nullptr},    /* GNU */
-  {ARG_TEST, "-help",                 parse_help,    nullptr},    /* GNU */
-  {ARG_TEST, "version",               parse_version, nullptr},    /* GNU */
-  {ARG_TEST, "-version",              parse_version, nullptr},    /* GNU */
   {0, nullptr, nullptr, nullptr}
 };
 
-- 
2.51.1


Reply via email to