summaryrefslogtreecommitdiff
path: root/bin/bbackupquery/bbackupquery.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'bin/bbackupquery/bbackupquery.cpp')
-rw-r--r--bin/bbackupquery/bbackupquery.cpp119
1 files changed, 64 insertions, 55 deletions
diff --git a/bin/bbackupquery/bbackupquery.cpp b/bin/bbackupquery/bbackupquery.cpp
index 90fa74b5..bc4cff13 100644
--- a/bin/bbackupquery/bbackupquery.cpp
+++ b/bin/bbackupquery/bbackupquery.cpp
@@ -30,6 +30,7 @@
#include <readline.h>
#endif
#endif
+
#ifdef HAVE_READLINE_HISTORY
#ifdef HAVE_READLINE_HISTORY_H
#include <readline/history.h>
@@ -92,49 +93,70 @@ void PrintUsageAndExit()
}
#ifdef HAVE_LIBREADLINE
-// copied from: http://tiswww.case.edu/php/chet/readline/readline.html#SEC44
+static BackupProtocolClient* pProtocol;
+static const Configuration* pConfig;
+static BackupQueries* pQueries;
+static std::vector<std::string> completions;
+static std::auto_ptr<BackupQueries::ParsedCommand> sapCmd;
-char * command_generator(const char *text, int state)
+char * completion_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)
+ if(state == 0)
{
- list_index = 0;
- len = strlen(text);
- }
+ completions.clear();
- /* Return the next name which partially matches from the command list. */
- while((name = commands[list_index].name))
- {
- list_index++;
+ std::string partialCommand(rl_line_buffer, rl_point);
+ sapCmd.reset(new BackupQueries::ParsedCommand(partialCommand,
+ false));
- if(::strncmp(name, text, len) == 0 && !(state--))
+ if(sapCmd->mArgCount == 0) // incomplete command
{
- return ::strdup(name);
+ completions = CompleteCommand(*sapCmd, text, *pProtocol,
+ *pConfig, *pQueries);
}
- }
+ else if(sapCmd->mInOptions)
+ {
+ completions = CompleteOptions(*sapCmd, text, *pProtocol,
+ *pConfig, *pQueries);
+ }
+ else if(sapCmd->mArgCount - 1 < MAX_COMPLETION_HANDLERS)
+ // sapCmd->mArgCount must be at least 1 if we're here
+ {
+ CompletionHandler handler =
+ sapCmd->pSpec->complete[sapCmd->mArgCount - 1];
+ if(handler != NULL)
+ {
+ completions = handler(*sapCmd, text, *pProtocol,
+ *pConfig, *pQueries);
+ }
- list_index = 0;
+ if(std::string(text) == "")
+ {
+ // additional options are also allowed here
+ std::vector<std::string> addOpts =
+ CompleteOptions(*sapCmd, text,
+ *pProtocol, *pConfig,
+ *pQueries);
+
+ for(std::vector<std::string>::iterator
+ i = addOpts.begin();
+ i != addOpts.end(); i++)
+ {
+ completions.push_back(*i);
+ }
+ }
+ }
+ }
- while((name = alias[list_index]))
+ if(state < 0 || state >= (int) completions.size())
{
- list_index++;
-
- if(::strncmp(name, text, len) == 0 && !(state--))
- {
- return ::strdup(name);
- }
+ rl_attempted_completion_over = 1;
+ return NULL;
}
- /* If no names matched, then return NULL. */
- return (char *) NULL;
+ return strdup(completions[state].c_str());
+ // string must be allocated with malloc() and will be freed
+ // by rl_completion_matches().
}
#ifdef HAVE_RL_COMPLETION_MATCHES
@@ -145,22 +167,7 @@ char * command_generator(const char *text, int state)
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.
- */
- #ifdef RL_COMPLETION_MATCHES
- if (start == 0)
- {
- matches = RL_COMPLETION_MATCHES(text, command_generator);
- }
- #endif
-
- return matches;
+ return RL_COMPLETION_MATCHES(text, completion_generator);
}
#endif // HAVE_LIBREADLINE
@@ -445,10 +452,9 @@ int main(int argc, const char *argv[])
int c = 0;
while(c < argc && !context.Stop())
{
- BackupQueries::ParsedCommand cmd(
- context.ParseCommand(argv[c++], true));
+ BackupQueries::ParsedCommand cmd(argv[c++], true);
- if(cmd.failed)
+ if(cmd.mFailed)
{
BOX_ERROR("Parse failed");
}
@@ -487,6 +493,10 @@ int main(int argc, const char *argv[])
/* Tell the completer that we want a crack first. */
rl_attempted_completion_function = bbackupquery_completion;
+ pProtocol = &connection;
+ pConfig = &conf;
+ pQueries = &context;
+
char *last_cmd = 0;
while(!context.Stop())
{
@@ -498,10 +508,9 @@ int main(int argc, const char *argv[])
break;
}
- BackupQueries::ParsedCommand cmd(
- context.ParseCommand(command, false));
+ BackupQueries::ParsedCommand cmd(command, false);
- if(cmd.failed)
+ if(cmd.mFailed)
{
BOX_ERROR("Parse failed");
}
@@ -541,8 +550,8 @@ int main(int argc, const char *argv[])
printf("query > ");
fflush(stdout);
std::string command(getLine.GetLine());
- BackupQueries::ParsedCommand cmd(
- context.ParseCommand(command, false));
+ BackupQueries::ParsedCommand cmd(command,
+ false);
context.DoCommand(cmd);
}
}