From 09f3ff129e3289bfd8d10b046be698665b53679f Mon Sep 17 00:00:00 2001 From: Kolja Waschk Date: Sat, 19 Apr 2008 10:25:09 +0000 Subject: [PATCH] [ 1946331 ] command completion support (Mike Frysinger) git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@1175 b68d4a1b-bc3d-0410-92ed-d4ac073336b7 --- jtag/ChangeLog | 2 ++ jtag/include/cmd.h | 1 + jtag/src/cmd/cmd.c | 60 ++++++++++++++++++++++++++++++++++++++++++---- jtag/src/jtag.c | 4 ++++ 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/jtag/ChangeLog b/jtag/ChangeLog index 86fcc67e..ec17588b 100644 --- a/jtag/ChangeLog +++ b/jtag/ChangeLog @@ -1,5 +1,7 @@ 2008-04-19 Kolja Waschk + * include/cmd.h, src/cmd/cmd.c, src/jtag.c: [ 1946331 ] command + completion support (by Mike Frysinger) * configure.ac, acinclude.m4: [ 1946114 ] make AC_PROG_SED workaround sane (Mike Frysinger) * include/jtag.h, src/cmd/detect.c, src/tap/detect.c: diff --git a/jtag/include/cmd.h b/jtag/include/cmd.h index 4629a763..9b74fdb9 100644 --- a/jtag/include/cmd.h +++ b/jtag/include/cmd.h @@ -45,6 +45,7 @@ typedef struct { extern const cmd_t *cmds[]; +char **cmd_completion( const char *text, int start, int end ); int cmd_run( chain_t *chain, char *params[] ); int cmd_params( char *params[] ); int cmd_get_number( char *s, unsigned int *i ); diff --git a/jtag/src/cmd/cmd.c b/jtag/src/cmd/cmd.c index bca268a2..93d6968c 100644 --- a/jtag/src/cmd/cmd.c +++ b/jtag/src/cmd/cmd.c @@ -26,6 +26,9 @@ #include #include +#ifdef HAVE_LIBREADLINE +#include +#endif #include "jtag.h" @@ -118,6 +121,38 @@ const cmd_t *cmds[] = { NULL /* last must be NULL */ }; +#ifdef HAVE_LIBREADLINE +static char * +cmd_find_next( const char *text, int state ) +{ + static size_t cmd_idx, len; + + if (!state) { + cmd_idx = 0; + len = strlen(text); + } + + while (cmds[cmd_idx]) { + char *name = cmds[cmd_idx++]->name; + if (!strncmp(name, text, len)) + return strdup(name); + } + + return NULL; +} + +char ** +cmd_completion( const char *text, int start, int end ) +{ + char **ret = NULL; + + if (start == 0) + ret = rl_completion_matches(text, cmd_find_next); + + return ret; +} +#endif + int cmd_test_cable( chain_t *chain ) { @@ -133,20 +168,37 @@ cmd_test_cable( chain_t *chain ) int cmd_run( chain_t *chain, char *params[] ) { - int i; + int i, pidx; + size_t len; if (!params[0]) return 1; - for (i = 0; cmds[i]; i++) + pidx = -1; + len = strlen(params[0]); + + for (i = 0; cmds[i]; ++i) { if (strcasecmp( cmds[i]->name, params[0] ) == 0) { - int r = cmds[i]->run( chain, params ); + int r; + run_cmd: + r = cmds[i]->run( chain, params ); if (r < 0) printf( _("%s: syntax error!\n"), params[0] ); return r; + } else if (strncasecmp( cmds[i]->name, params[0], len ) == 0) { + if (pidx == -1) + pidx = i; + else + pidx = -2; } + } + + switch (pidx) { + case -2: printf( _("%s: Ambiguous command\n"), params[0] ); break; + case -1: printf( _("%s: unknown command\n"), params[0] ); break; + default: i = pidx; goto run_cmd; + } - printf( _("%s: unknown command\n"), params[0] ); return 1; } diff --git a/jtag/src/jtag.c b/jtag/src/jtag.c index 99af2338..f5506d54 100644 --- a/jtag/src/jtag.c +++ b/jtag/src/jtag.c @@ -463,6 +463,10 @@ main( int argc, char *const argv[] ) /* Parse and execute the RC file */ go = norc ? 1 : jtag_parse_rc( chain ); +#ifdef HAVE_LIBREADLINE + rl_attempted_completion_function = cmd_completion; +#endif + if (go) { #ifdef HAVE_READLINE_HISTORY