summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris+github@qwirx.com>2010-02-25 23:20:27 +0000
committerChris Wilson <chris+github@qwirx.com>2010-02-25 23:20:27 +0000
commit27ab8a2537deaff65a9bb68b2a03bb267361e91f (patch)
tree2225f568915e1d1dac8e9fb1cb0f51d127a88f9b
parent25203d94333f492a928278b1abb8642302242502 (diff)
First attempt at tab completion for readline/libedit in bbackupquery,
with commands and local file names, because it's easy and will help to find compatibility problems.
-rw-r--r--bin/bbackupquery/BackupQueries.cpp76
-rw-r--r--bin/bbackupquery/BackupQueries.h33
-rw-r--r--bin/bbackupquery/bbackupquery.cpp72
3 files changed, 130 insertions, 51 deletions
diff --git a/bin/bbackupquery/BackupQueries.cpp b/bin/bbackupquery/BackupQueries.cpp
index f799ab43..2a99c077 100644
--- a/bin/bbackupquery/BackupQueries.cpp
+++ b/bin/bbackupquery/BackupQueries.cpp
@@ -63,6 +63,30 @@
#define COMPARE_RETURN_ERROR 3
#define COMMAND_RETURN_ERROR 4
+// Data about commands
+QueryCommandSpecification commands[] =
+{
+ { "quit", "" },
+ { "exit", "" },
+ { "list", "rodIFtTash", },
+ { "pwd", "" },
+ { "cd", "od" },
+ { "lcd", "" },
+ { "sh", "" },
+ { "getobject", "" },
+ { "get", "i" },
+ { "compare", "alcqAEQ" },
+ { "restore", "drif" },
+ { "help", "" },
+ { "usage", "m" },
+ { "undelete", "" },
+ { "delete", "" },
+ { NULL, NULL }
+};
+
+const char *alias[] = {"ls", 0};
+const int aliasIs[] = {Command_List, 0};
+
// --------------------------------------------------------------------------
//
// Function
@@ -100,12 +124,6 @@ BackupQueries::~BackupQueries()
{
}
-typedef struct
-{
- const char* name;
- const char* opts;
-} QueryCommandSpecification;
-
// --------------------------------------------------------------------------
//
// Function
@@ -206,51 +224,7 @@ void BackupQueries::DoCommand(const char *Command, bool isFromCommandLine)
// blank command
return;
}
-
- // Data about commands
- static QueryCommandSpecification commands[] =
- {
- { "quit", "" },
- { "exit", "" },
- { "list", "rodIFtTash", },
- { "pwd", "" },
- { "cd", "od" },
- { "lcd", "" },
- { "sh", "" },
- { "getobject", "" },
- { "get", "i" },
- { "compare", "alcqAEQ" },
- { "restore", "drif" },
- { "help", "" },
- { "usage", "m" },
- { "undelete", "" },
- { "delete", "" },
- { NULL, NULL }
- };
-
- typedef enum
- {
- Command_Quit = 0,
- Command_Exit,
- Command_List,
- Command_pwd,
- Command_cd,
- Command_lcd,
- Command_sh,
- Command_GetObject,
- Command_Get,
- Command_Compare,
- Command_Restore,
- Command_Help,
- Command_Usage,
- Command_Undelete,
- Command_Delete,
- }
- CommandType;
-
- static const char *alias[] = {"ls", 0};
- static const int aliasIs[] = {Command_List, 0};
-
+
// Work out which command it is...
int cmd = 0;
while(commands[cmd].name != 0 && ::strcmp(cmdElements[0].c_str(), commands[cmd].name) != 0)
diff --git a/bin/bbackupquery/BackupQueries.h b/bin/bbackupquery/BackupQueries.h
index 392aa428..dfca7130 100644
--- a/bin/bbackupquery/BackupQueries.h
+++ b/bin/bbackupquery/BackupQueries.h
@@ -20,6 +20,39 @@ class BackupProtocolClient;
class Configuration;
class ExcludeList;
+typedef struct
+{
+ const char* name;
+ const char* opts;
+}
+QueryCommandSpecification;
+
+// Data about commands
+extern QueryCommandSpecification commands[];
+
+typedef enum
+{
+ Command_Quit = 0,
+ Command_Exit,
+ Command_List,
+ Command_pwd,
+ Command_cd,
+ Command_lcd,
+ Command_sh,
+ Command_GetObject,
+ Command_Get,
+ Command_Compare,
+ Command_Restore,
+ Command_Help,
+ Command_Usage,
+ Command_Undelete,
+ Command_Delete,
+}
+CommandType;
+
+extern const char *alias[];
+extern const int aliasIs[];
+
// --------------------------------------------------------------------------
//
// Class
diff --git a/bin/bbackupquery/bbackupquery.cpp b/bin/bbackupquery/bbackupquery.cpp
index 5aa7e97e..6d697087 100644
--- a/bin/bbackupquery/bbackupquery.cpp
+++ b/bin/bbackupquery/bbackupquery.cpp
@@ -74,6 +74,72 @@ void PrintUsageAndExit()
exit(1);
}
+#ifdef HAVE_LIBREADLINE
+// copied from: http://tiswww.case.edu/php/chet/readline/readline.html#SEC44
+
+char * command_generator(const char *text, int state)
+{
+ static int list_index, len;
+ const char *name;
+
+ /*
+ * If this is a new word to complete, initialize now. This includes
+ * saving the length of TEXT for efficiency, and initializing the index
+ * variable to 0.
+ */
+ if(!state)
+ {
+ list_index = 0;
+ len = strlen(text);
+ }
+
+ /* Return the next name which partially matches from the command list. */
+ while((name = commands[list_index].name))
+ {
+ list_index++;
+
+ if(::strncmp(name, text, len) == 0 && !(state--))
+ {
+ return ::strdup(name);
+ }
+ }
+
+ list_index = 0;
+
+ while((name = alias[list_index]))
+ {
+ list_index++;
+
+ if(::strncmp(name, text, len) == 0 && !(state--))
+ {
+ return ::strdup(name);
+ }
+ }
+
+ /* If no names matched, then return NULL. */
+ return (char *) NULL;
+}
+
+char ** bbackupquery_completion(const char *text, int start, int end)
+{
+ char **matches;
+
+ matches = (char **)NULL;
+
+ /* If this word is at the start of the line, then it is a command
+ * to complete. Otherwise it is the name of a file in the current
+ * directory.
+ */
+ if (start == 0)
+ {
+ matches = rl_completion_matches(text, command_generator);
+ }
+
+ return matches;
+}
+
+#endif // HAVE_LIBREADLINE
+
int main(int argc, const char *argv[])
{
int returnCode = 0;
@@ -369,6 +435,12 @@ int main(int argc, const char *argv[])
#ifdef HAVE_READLINE_HISTORY
using_history();
#endif
+ /* Allow conditional parsing of the ~/.inputrc file. */
+ rl_readline_name = "bbackupquery";
+
+ /* Tell the completer that we want a crack first. */
+ rl_attempted_completion_function = bbackupquery_completion;
+
char *last_cmd = 0;
while(!context.Stop())
{