aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2012-10-01 21:56:07 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2012-10-01 21:56:07 +0300
commit179bf25f249a8ee7456e9f3e47f930014b0e5f90 (patch)
tree598f75c13a2c88c797459a5d17e37c25fd6e9cbc /src
parentddb280198adcada561b8e72c79b92d50a05b3e78 (diff)
downloadeclat-179bf25f249a8ee7456e9f3e47f930014b0e5f90.tar.gz
eclat-179bf25f249a8ee7456e9f3e47f930014b0e5f90.tar.bz2
Improve command matching
* src/eclat.c (name_matches): New function. (find_command_name): Use it. (main): Handle --match-commands. * src/cmdline.opt: New option: --match-commands. * doc/eclat.1: Document new command matching algorithm.
Diffstat (limited to 'src')
-rw-r--r--src/cmdline.opt6
-rw-r--r--src/eclat.c62
2 files changed, 61 insertions, 7 deletions
diff --git a/src/cmdline.opt b/src/cmdline.opt
index 7726416..84b495f 100644
--- a/src/cmdline.opt
+++ b/src/cmdline.opt
@@ -57,6 +57,12 @@ BEGIN
preprocess_only = 1;
END
+OPTION(match-command,m,,
+ [<find matching command names>])
+BEGIN
+ match_command_mode = 1;
+END
+
GROUP(Modifiers)
OPTION(config-file,c,FILE,
diff --git a/src/eclat.c b/src/eclat.c
index 6af9eb5..a0a7be0 100644
--- a/src/eclat.c
+++ b/src/eclat.c
@@ -19,6 +19,7 @@
char *conffile = SYSCONFDIR "/eclat.conf" ;
int lint_mode;
int dry_run_mode;
+int match_command_mode;
int preprocess_only = 0;
char *endpoint = "ec2.amazonaws.com";
@@ -263,25 +264,55 @@ listcmd()
putchar('\n');
}
+#define NO_MATCH 0
+#define EXACT_MATCH 1
+#define PARTIAL_MATCH 2
+
+static int
+name_matches(const char *p, const char *q)
+{
+ int match = EXACT_MATCH;
+
+ for (;; p++, q++) {
+ if (*p == 0)
+ return *q == 0 ? match : NO_MATCH;
+ else if (*q == 0)
+ return PARTIAL_MATCH;
+ else if (*p == *q)
+ continue;
+ else if (*q == '-') {
+ for (; *p != '-'; p++)
+ if (!*p)
+ return NO_MATCH;
+ match = PARTIAL_MATCH;
+ } else
+ break;
+ }
+ return NO_MATCH;
+}
+
struct command *
find_command_name(const char *name)
{
struct command *cp, *match = NULL;
- size_t namelen = strlen(name);
for (cp = cmdtab; cp < cmdtab + cmdcnt; cp++) {
- if (!strncmp(cp->ident, name, namelen)) {
- if (strlen(cp->ident) == namelen)
- return cp;
- else if (!match)
+ switch (name_matches(cp->ident, name)) {
+ case NO_MATCH:
+ break;
+ case EXACT_MATCH:
+ return cp;
+ case PARTIAL_MATCH:
+ if (!match)
match = cp;
else {
/* Second match */
- err("ambiguous command %s:");
+ err("ambiguous command %s:", name);
err(" %s", match->ident);
err(" %s", cp->ident);
while (++cp < cmdtab + cmdcnt)
- if (!strncmp(cp->ident, name, namelen))
+ if (name_matches(cp->ident, name) !=
+ NO_MATCH)
err(" %s", cp->ident);
exit(EX_USAGE);
}
@@ -290,6 +321,16 @@ find_command_name(const char *name)
return match;
}
+static void
+print_matching_commands(const char *pat)
+{
+ struct command *cp;
+
+ for (cp = cmdtab; cp < cmdtab + cmdcnt; cp++)
+ if (name_matches(cp->ident, pat) != NO_MATCH)
+ printf("%s\n", cp->ident);
+}
+
struct command *
find_command_tag(const char *tag)
{
@@ -549,6 +590,13 @@ main(int argc, char **argv)
argc -= index;
argv += index;
+ if (match_command_mode) {
+ if (argc != 1)
+ die(EX_USAGE, "wrong number of arguments");
+ print_matching_commands(argv[0]);
+ return 0;
+ }
+
if (argc) {
command = find_command_name(argv[0]);
if (!command)

Return to:

Send suggestions and report system problems to the System administrator.