1 /*-------------------------------------------------------------------------
2 * C-Pluff, a plug-in framework for C
3 * Copyright 2007 Johannes Lehtinen
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *-----------------------------------------------------------------------*/
24 // GNU readline based command line input
29 #include <readline/readline.h>
30 #include <readline/history.h>
33 static cp_plugin_info_t **plugins = NULL;
35 static char *cp_console_compl_cmdgen(const char *text, int state) {
41 textlen = strlen(text);
43 while (commands[counter].name != NULL && strncmp(text, commands[counter].name, textlen)) {
46 if (commands[counter].name == NULL) {
49 char *buffer = strdup(commands[counter].name);
55 static char *cp_console_compl_flagsgen(const char *text, int state) {
61 textlen = strlen(text);
63 while(load_flags[counter].name != NULL && strncmp(text, load_flags[counter].name, textlen)) {
66 if (load_flags[counter].name == NULL) {
69 char *buffer = strdup(load_flags[counter].name);
75 static char *cp_console_compl_loggen(const char *text, int state) {
81 textlen = strlen(text);
83 while (log_levels[counter].name != NULL && strncmp(text, log_levels[counter].name, textlen)) {
86 if (log_levels[counter].name == NULL) {
89 char *buffer = strdup(log_levels[counter].name);
95 static char *cp_console_compl_plugingen(const char *text, int state) {
101 textlen = strlen(text);
102 if (plugins != NULL) {
103 cp_release_info(context, plugins);
105 plugins = cp_get_plugins_info(context, NULL, NULL);
107 if (plugins != NULL) {
108 while (plugins[counter] != NULL && strncmp(text, plugins[counter]->identifier, textlen)) {
111 if (plugins[counter] == NULL) {
112 cp_release_info(context, plugins);
116 char *buffer = strdup(plugins[counter]->identifier);
125 static char **cp_console_completion(const char *text, int start, int end) {
127 char **matches = NULL;
129 // Search for start and end of command
130 for (cs = 0; cs < start && isspace(rl_line_buffer[cs]); cs++);
131 for (ce = cs; ce <= start && !isspace(rl_line_buffer[ce]); ce++);
133 // If no command entered yet, use command completion
135 matches = rl_completion_matches(text, cp_console_compl_cmdgen);
136 rl_attempted_completion_over = 1;
139 // Otherwise check if known command and complete accordingly
142 while (commands[j].name != NULL
143 && strncmp(rl_line_buffer + cs, commands[j].name, ce - cs)) {
146 if (commands[j].name != NULL) {
147 switch(commands[j].arg_completion) {
151 matches = rl_completion_matches(text, cp_console_compl_flagsgen);
152 rl_attempted_completion_over = 1;
154 case CPC_COMPL_LOG_LEVEL:
155 matches = rl_completion_matches(text, cp_console_compl_loggen);
156 rl_attempted_completion_over = 1;
158 case CPC_COMPL_PLUGIN:
159 matches = rl_completion_matches(text, cp_console_compl_plugingen);
160 rl_attempted_completion_over = 1;
163 rl_attempted_completion_over = 1;
167 rl_attempted_completion_over = 1;
173 CP_HIDDEN void cmdline_init(void) {
174 rl_readline_name = PACKAGE_NAME;
175 rl_attempted_completion_function = cp_console_completion;
178 CP_HIDDEN char *cmdline_input(const char *prompt) {
179 static char *cmdline = NULL;
181 // Free previously returned command line, if any
182 if (cmdline != NULL) {
187 // Obtain new command line and record it for history
188 cmdline = readline(prompt);
189 if (cmdline != NULL && *cmdline != '\0') {
190 add_history(cmdline);
196 CP_HIDDEN void cmdline_destroy(void) {
197 if (plugins != NULL) {
198 cp_release_info(context, plugins);