summaryrefslogtreecommitdiff
path: root/service/protocol-plugin/lib/cpluff/console
diff options
context:
space:
mode:
Diffstat (limited to 'service/protocol-plugin/lib/cpluff/console')
-rw-r--r--service/protocol-plugin/lib/cpluff/console/Makefile.am16
-rw-r--r--service/protocol-plugin/lib/cpluff/console/cmdinput_basic.c61
-rw-r--r--service/protocol-plugin/lib/cpluff/console/cmdinput_readline.c201
-rw-r--r--service/protocol-plugin/lib/cpluff/console/console.c938
-rw-r--r--service/protocol-plugin/lib/cpluff/console/console.h176
5 files changed, 1392 insertions, 0 deletions
diff --git a/service/protocol-plugin/lib/cpluff/console/Makefile.am b/service/protocol-plugin/lib/cpluff/console/Makefile.am
new file mode 100644
index 000000000..f972aaafb
--- /dev/null
+++ b/service/protocol-plugin/lib/cpluff/console/Makefile.am
@@ -0,0 +1,16 @@
+## Process this file with automake to produce Makefile.in.
+
+# Copyright 2007 Johannes Lehtinen
+# This Makefile is free software; Johannes Lehtinen gives unlimited
+# permission to copy, distribute and modify it.
+
+LIBS = @LIB_READLINE@ @LIBS_OTHER@ @LTLIBINTL@ @LIBS@
+
+bin_PROGRAMS = cpluff-console
+
+cpluff_console_SOURCES = console.c console.h PluginManager.c
+if HAVE_READLINE
+cpluff_console_SOURCES += cmdinput_readline.c
+else
+cpluff_console_SOURCES += cmdinput_basic.c
+endif
diff --git a/service/protocol-plugin/lib/cpluff/console/cmdinput_basic.c b/service/protocol-plugin/lib/cpluff/console/cmdinput_basic.c
new file mode 100644
index 000000000..ee8b76b52
--- /dev/null
+++ b/service/protocol-plugin/lib/cpluff/console/cmdinput_basic.c
@@ -0,0 +1,61 @@
+/*-------------------------------------------------------------------------
+ * C-Pluff, a plug-in framework for C
+ * Copyright 2007 Johannes Lehtinen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *-----------------------------------------------------------------------*/
+
+// Basic command line input functionality
+
+#include <stdio.h>
+#include <string.h>
+#include "console.h"
+
+#define CMDLINE_SIZE 256
+
+CP_HIDDEN void cmdline_init(void) {}
+
+CP_HIDDEN char *cmdline_input(const char *prompt) {
+ static char cmdline[CMDLINE_SIZE];
+ int i, success = 0;
+
+ do {
+ fputs(prompt, stdout);
+ if (fgets(cmdline, CMDLINE_SIZE, stdin) == NULL) {
+ return NULL;
+ }
+ if (strlen(cmdline) == CMDLINE_SIZE - 1
+ && cmdline[CMDLINE_SIZE - 2] != '\n') {
+ char c;
+ do {
+ c = getchar();
+ } while (c != '\n');
+ fputs(_("ERROR: Command line is too long.\n"), stderr);
+ } else {
+ success = 1;
+ }
+ } while (!success);
+ i = strlen(cmdline);
+ if (i > 0 && cmdline[i - 1] == '\n') {
+ cmdline[i - 1] = '\0';
+ }
+ return cmdline;
+}
+
+CP_HIDDEN void cmdline_destroy(void) {}
diff --git a/service/protocol-plugin/lib/cpluff/console/cmdinput_readline.c b/service/protocol-plugin/lib/cpluff/console/cmdinput_readline.c
new file mode 100644
index 000000000..e383c8fab
--- /dev/null
+++ b/service/protocol-plugin/lib/cpluff/console/cmdinput_readline.c
@@ -0,0 +1,201 @@
+/*-------------------------------------------------------------------------
+ * C-Pluff, a plug-in framework for C
+ * Copyright 2007 Johannes Lehtinen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *-----------------------------------------------------------------------*/
+
+// GNU readline based command line input
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <readline/readline.h>
+#include <readline/history.h>
+#include "console.h"
+
+static cp_plugin_info_t **plugins = NULL;
+
+static char *cp_console_compl_cmdgen(const char *text, int state) {
+ static int counter;
+ static int textlen;
+
+ if (!state) {
+ counter = 0;
+ textlen = strlen(text);
+ }
+ while (commands[counter].name != NULL && strncmp(text, commands[counter].name, textlen)) {
+ counter++;
+ }
+ if (commands[counter].name == NULL) {
+ return NULL;
+ } else {
+ char *buffer = strdup(commands[counter].name);
+ counter++;
+ return buffer;
+ }
+}
+
+static char *cp_console_compl_flagsgen(const char *text, int state) {
+ static int counter;
+ static int textlen;
+
+ if (!state) {
+ counter = 0;
+ textlen = strlen(text);
+ }
+ while(load_flags[counter].name != NULL && strncmp(text, load_flags[counter].name, textlen)) {
+ counter++;
+ }
+ if (load_flags[counter].name == NULL) {
+ return NULL;
+ } else {
+ char *buffer = strdup(load_flags[counter].name);
+ counter++;
+ return buffer;
+ }
+}
+
+static char *cp_console_compl_loggen(const char *text, int state) {
+ static int counter;
+ static int textlen;
+
+ if (!state) {
+ counter = 0;
+ textlen = strlen(text);
+ }
+ while (log_levels[counter].name != NULL && strncmp(text, log_levels[counter].name, textlen)) {
+ counter++;
+ }
+ if (log_levels[counter].name == NULL) {
+ return NULL;
+ } else {
+ char *buffer = strdup(log_levels[counter].name);
+ counter++;
+ return buffer;
+ }
+}
+
+static char *cp_console_compl_plugingen(const char *text, int state) {
+ static int counter;
+ static int textlen;
+
+ if (!state) {
+ counter = 0;
+ textlen = strlen(text);
+ if (plugins != NULL) {
+ cp_release_info(context, plugins);
+ }
+ plugins = cp_get_plugins_info(context, NULL, NULL);
+ }
+ if (plugins != NULL) {
+ while (plugins[counter] != NULL && strncmp(text, plugins[counter]->identifier, textlen)) {
+ counter++;
+ }
+ if (plugins[counter] == NULL) {
+ cp_release_info(context, plugins);
+ plugins = NULL;
+ return NULL;
+ } else {
+ char *buffer = strdup(plugins[counter]->identifier);
+ counter++;
+ return buffer;
+ }
+ } else {
+ return NULL;
+ }
+}
+
+static char **cp_console_completion(const char *text, int start, int end) {
+ int cs, ce;
+ char **matches = NULL;
+
+ // Search for start and end of command
+ for (cs = 0; cs < start && isspace(rl_line_buffer[cs]); cs++);
+ for (ce = cs; ce <= start && !isspace(rl_line_buffer[ce]); ce++);
+
+ // If no command entered yet, use command completion
+ if (ce >= start) {
+ matches = rl_completion_matches(text, cp_console_compl_cmdgen);
+ rl_attempted_completion_over = 1;
+ }
+
+ // Otherwise check if known command and complete accordingly
+ else {
+ int j = 0;
+ while (commands[j].name != NULL
+ && strncmp(rl_line_buffer + cs, commands[j].name, ce - cs)) {
+ j++;
+ }
+ if (commands[j].name != NULL) {
+ switch(commands[j].arg_completion) {
+ case CPC_COMPL_FILE:
+ break;
+ case CPC_COMPL_FLAG:
+ matches = rl_completion_matches(text, cp_console_compl_flagsgen);
+ rl_attempted_completion_over = 1;
+ break;
+ case CPC_COMPL_LOG_LEVEL:
+ matches = rl_completion_matches(text, cp_console_compl_loggen);
+ rl_attempted_completion_over = 1;
+ break;
+ case CPC_COMPL_PLUGIN:
+ matches = rl_completion_matches(text, cp_console_compl_plugingen);
+ rl_attempted_completion_over = 1;
+ break;
+ default:
+ rl_attempted_completion_over = 1;
+ break;
+ }
+ } else {
+ rl_attempted_completion_over = 1;
+ }
+ }
+ return matches;
+}
+
+CP_HIDDEN void cmdline_init(void) {
+ rl_readline_name = PACKAGE_NAME;
+ rl_attempted_completion_function = cp_console_completion;
+}
+
+CP_HIDDEN char *cmdline_input(const char *prompt) {
+ static char *cmdline = NULL;
+
+ // Free previously returned command line, if any
+ if (cmdline != NULL) {
+ free(cmdline);
+ cmdline = NULL;
+ }
+
+ // Obtain new command line and record it for history
+ cmdline = readline(prompt);
+ if (cmdline != NULL && *cmdline != '\0') {
+ add_history(cmdline);
+ }
+
+ return cmdline;
+}
+
+CP_HIDDEN void cmdline_destroy(void) {
+ if (plugins != NULL) {
+ cp_release_info(context, plugins);
+ plugins = NULL;
+ }
+}
diff --git a/service/protocol-plugin/lib/cpluff/console/console.c b/service/protocol-plugin/lib/cpluff/console/console.c
new file mode 100644
index 000000000..539809341
--- /dev/null
+++ b/service/protocol-plugin/lib/cpluff/console/console.c
@@ -0,0 +1,938 @@
+/*-------------------------------------------------------------------------
+ * C-Pluff, a plug-in framework for C
+ * Copyright 2007 Johannes Lehtinen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *-----------------------------------------------------------------------*/
+
+// Core console logic
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+#ifdef HAVE_GETTEXT
+#include <locale.h>
+#endif
+#include <assert.h>
+#include <cpluff.h>
+#include "console.h"
+
+/* ------------------------------------------------------------------------
+ * Function declarations
+ * ----------------------------------------------------------------------*/
+
+// Function declarations for command implementations
+static void cmd_help(int argc, char *argv[]);
+static void cmd_set_log_level(int argc, char *argv[]);
+static void cmd_register_pcollection(int argc, char *argv[]);
+static void cmd_unregister_pcollection(int argc, char *argv[]);
+static void cmd_unregister_pcollections(int argc, char *argv[]);
+static void cmd_load_plugin(int argc, char *argv[]);
+static void cmd_scan_plugins(int argc, char *argv[]);
+static void cmd_list_plugins(int argc, char *argv[]);
+static void cmd_show_plugin_info(int argc, char *argv[]);
+static void cmd_list_ext_points(int argc, char *argv[]);
+static void cmd_list_extensions(int argc, char *argv[]);
+static void cmd_set_context_args(int argc, char *argv[]);
+static void cmd_start_plugin(int argc, char *argv[]);
+static void cmd_run_plugins_step(int argc, char *argv[]);
+static void cmd_run_plugins(int argc, char *argv[]);
+static void cmd_stop_plugin(int argc, char *argv[]);
+static void cmd_stop_plugins(int argc, char *argv[]);
+static void cmd_uninstall_plugin(int argc, char *argv[]);
+static void cmd_uninstall_plugins(int argc, char *argv[]);
+static void cmd_exit(int argc, char *argv[]);
+static void cmd_findResourcebyType(int argc, char*argv[]);
+
+/* ------------------------------------------------------------------------
+ * Variables
+ * ----------------------------------------------------------------------*/
+
+/// The plug-in context
+CP_HIDDEN cp_context_t *context;
+
+/// The available commands
+CP_HIDDEN const command_info_t commands[] = {
+ { "help", N_("displays available commands"), cmd_help, CPC_COMPL_NONE },
+ { "set-log-level", N_("sets the displayed log level"), cmd_set_log_level, CPC_COMPL_LOG_LEVEL },
+ { "register-collection", N_("registers a plug-in collection"), cmd_register_pcollection, CPC_COMPL_FILE },
+ { "unregister-collection", N_("unregisters a plug-in collection"), cmd_unregister_pcollection, CPC_COMPL_FILE },
+ { "unregister-collections", N_("unregisters all plug-in collections"), cmd_unregister_pcollections, CPC_COMPL_NONE },
+ { "load-plugin", N_("loads and installs a plug-in from the specified path"), cmd_load_plugin, CPC_COMPL_FILE },
+ { "scan-plugins", N_("scans plug-ins in the registered plug-in collections"), cmd_scan_plugins, CPC_COMPL_FLAG },
+ { "set-context-args", N_("sets context startup arguments"), cmd_set_context_args, CPC_COMPL_FILE },
+ { "start-plugin", N_("starts a plug-in"), cmd_start_plugin, CPC_COMPL_PLUGIN },
+ { "run-plugins-step", N_("runs one plug-in run function"), cmd_run_plugins_step, CPC_COMPL_NONE },
+ { "run-plugins", N_("runs plug-in run functions until all work is done"), cmd_run_plugins, CPC_COMPL_NONE },
+ { "stop-plugin", N_("stops a plug-in"), cmd_stop_plugin, CPC_COMPL_PLUGIN },
+ { "stop-plugins", N_("stops all plug-ins"), cmd_stop_plugins, CPC_COMPL_NONE },
+ { "uninstall-plugin", N_("uninstalls a plug-in"), cmd_uninstall_plugin, CPC_COMPL_PLUGIN },
+ { "uninstall-plugins", N_("uninstalls all plug-ins"), cmd_uninstall_plugins, CPC_COMPL_NONE },
+ { "list-plugins", N_("lists the installed plug-ins"), cmd_list_plugins, CPC_COMPL_NONE },
+ { "list-ext-points", N_("lists the installed extension points"), cmd_list_ext_points, CPC_COMPL_NONE },
+ { "list-extensions", N_("lists the installed extensions"), cmd_list_extensions, CPC_COMPL_NONE },
+ { "show-plugin-info", N_("shows static plug-in information"), cmd_show_plugin_info, CPC_COMPL_PLUGIN },
+ { "quit", N_("quits the program"), cmd_exit, CPC_COMPL_NONE },
+ { "exit", N_("quits the program"), cmd_exit, CPC_COMPL_NONE },
+ { "findResourcebyType", N_("findResourcebyType"),cmd_findResourcebyType,CPC_COMPL_NONE },
+ { NULL, NULL, NULL, CPC_COMPL_NONE }
+};
+
+/// The available load flags
+CP_HIDDEN const flag_info_t load_flags[] = {
+ { "upgrade", N_("enables upgrades of installed plug-ins"), CP_SP_UPGRADE },
+ { "stop-all-on-upgrade", N_("stops all plug-ins on first upgrade"), CP_SP_STOP_ALL_ON_UPGRADE },
+ { "stop-all-on-install", N_("stops all plug-ins on first install or upgrade"), CP_SP_STOP_ALL_ON_INSTALL },
+ { "restart-active", N_("restarts the currently active plug-ins after the scan"), CP_SP_RESTART_ACTIVE },
+ { NULL, NULL, -1 }
+};
+
+/// The available log levels
+CP_HIDDEN const log_level_info_t log_levels[] = {
+ { "debug", N_("detailed debug messages"), CP_LOG_DEBUG },
+ { "info", N_("informational messages"), CP_LOG_INFO },
+ { "warning", N_("warnings about possible problems"), CP_LOG_WARNING },
+ { "error", N_("error messages"), CP_LOG_ERROR },
+ { "none", N_("disable logging"), CP_LOG_ERROR + 1 },
+ { NULL, NULL, -1 }
+};
+
+
+/* ------------------------------------------------------------------------
+ * Function definitions
+ * ----------------------------------------------------------------------*/
+
+/**
+ * Parses a command line (in place) into white-space separated elements.
+ * Returns the number of elements and the pointer to argument table including
+ * command and arguments. The argument table is valid until the next call
+ * to this function.
+ *
+ * @param cmdline the command line to be parsed
+ * @param argv pointer to the argument table is stored here
+ * @return the number of command line elements, or -1 on failure
+ */
+static int cmdline_parse(char *cmdline, char **argv[]) {
+ static char *sargv[16];
+ int i, argc;
+
+ for (i = 0; isspace(cmdline[i]); i++);
+ for (argc = 0; cmdline[i] != '\0' && argc < 16; argc++) {
+ sargv[argc] = cmdline + i;
+ while (cmdline[i] != '\0' && !isspace(cmdline[i])) {
+ i++;
+ }
+ if (cmdline[i] != '\0') {
+ cmdline[i++] = '\0';
+ while (isspace(cmdline[i])) {
+ i++;
+ }
+ }
+ }
+ if (cmdline[i] != '\0') {
+ fputs(_("Command has too many arguments.\n"), stdout);
+ return -1;
+ } else {
+ *argv = sargv;
+ return argc;
+ }
+}
+
+static void cmd_exit(int argc, char *argv[]) {
+
+ // Uninitialize input
+ cmdline_destroy();
+
+ // Destroy C-Pluff framework
+ cp_destroy();
+
+ // Exit program
+ exit(0);
+}
+
+static void cmd_help(int argc, char *argv[]) {
+ int i;
+
+ fputs(_("The following commands are available:\n"), stdout);
+ for (i = 0; commands[i].name != NULL; i++) {
+ printf(" %s - %s\n", commands[i].name, _(commands[i].description));
+ }
+}
+
+static void logger(cp_log_severity_t severity, const char *msg, const char *apid, void *dummy) {
+ const char *level;
+ switch (severity) {
+ case CP_LOG_DEBUG:
+ /* TRANSLATORS: A tag for debug level log entries. */
+ level = _("DEBUG");
+ break;
+ case CP_LOG_INFO:
+ /* TRANSLATORS: A tag for info level log entries. */
+ level = _("INFO");
+ break;
+ case CP_LOG_WARNING:
+ /* TRANSLATORS: A tag for warning level log entries. */
+ level = _("WARNING");
+ break;
+ case CP_LOG_ERROR:
+ /* TRANSLATORS: A tag for error level log entries. */
+ level = _("ERROR");
+ break;
+ default:
+ /* TRANSLATORS: A tag for unknown severity level. */
+ level = _("UNKNOWN");
+ break;
+ }
+ fprintf(stderr, "C-Pluff: %s: [%s] %s\n",
+ level,
+ apid != NULL ? apid :
+ /* TRANSLATORS: Used when displaying log messages originating
+ from console activities. */
+ _("console"),
+ msg);
+}
+
+static void cmd_set_log_level(int argc, char *argv[]) {
+ if (argc != 2) {
+ /* TRANSLATORS: Usage instructions for setting log level */
+ printf(_("Usage: %s <level>\n"), argv[0]);
+ } else {
+ int i;
+
+ for (i = 0; log_levels[i].name != NULL; i++) {
+ if (!strcmp(argv[1], log_levels[i].name)) {
+ break;
+ }
+ }
+ if (log_levels[i].name == NULL) {
+ printf(_("Unknown log level %s.\n"), argv[1]);
+ fputs(_("Available log levels are:\n"), stdout);
+ for (i = 0; log_levels[i].name != NULL; i++) {
+ printf(" %s - %s\n", log_levels[i].name, _(log_levels[i].description));
+ }
+ } else {
+ if (log_levels[i].level <= CP_LOG_ERROR) {
+ cp_register_logger(context, logger, NULL, log_levels[i].level);
+ } else {
+ cp_unregister_logger(context, logger);
+ }
+ /* TRANSLATORS: The first %s is the log level name and the second the localized log level description. */
+ printf(_("Using display log level %s (%s).\n"), log_levels[i].name, _(log_levels[i].description));
+ }
+ }
+}
+
+static const char *status_to_desc(cp_status_t status) {
+ switch (status) {
+ case CP_OK:
+ /* TRANSLATORS: Return status for a successfull API call */
+ return _("success");
+ case CP_ERR_RESOURCE:
+ return _("insufficient system resources");
+ case CP_ERR_UNKNOWN:
+ return _("an unknown object was specified");
+ case CP_ERR_IO:
+ return _("an input or output error");
+ case CP_ERR_MALFORMED:
+ return _("a malformed plug-in descriptor");
+ case CP_ERR_CONFLICT:
+ return _("a plug-in or symbol conflicts with an existing one");
+ case CP_ERR_DEPENDENCY:
+ return _("unsatisfiable dependencies");
+ case CP_ERR_RUNTIME:
+ return _("a plug-in runtime library encountered an error");
+ default:
+ return _("unknown error code");
+ }
+}
+
+static void api_failed(const char *func, cp_status_t status) {
+ printf(_("API function %s failed with error code %d (%s).\n"),
+ func,
+ status,
+ status_to_desc(status));
+}
+
+static void cmd_register_pcollection(int argc, char *argv[]) {
+ cp_status_t status;
+
+ if (argc != 2) {
+ /* TRANSLATORS: Usage instructions for registering a plug-in collection */
+ printf(_("Usage: %s <path>\n"), argv[0]);
+ } else if ((status = cp_register_pcollection(context, argv[1])) != CP_OK) {
+ api_failed("cp_register_pcollection", status);
+ } else {
+ printf(_("Registered a plug-in collection in path %s.\n"), argv[1]);
+ }
+}
+
+static void cmd_unregister_pcollection(int argc, char *argv[]) {
+ if (argc != 2) {
+ /* TRANSLATORS: Usage instructions for unregistering a plug-in collection */
+ printf(_("Usage: %s <path>\n"), argv[0]);
+ } else {
+ cp_unregister_pcollection(context, argv[1]);
+ printf(_("Unregistered a plug-in collection in path %s.\n"), argv[1]);
+ }
+}
+
+static void cmd_unregister_pcollections(int argc, char *argv[]) {
+ if (argc != 1) {
+ /* TRANSLATORS: Usage instructions for unregistering all plug-in collections */
+ printf(_("Usage: %s\n"), argv[0]);
+ } else {
+ cp_unregister_pcollections(context);
+ fputs(_("Unregistered all plug-in collections.\n"), stdout);
+ }
+}
+
+static void cmd_load_plugin(int argc, char *argv[]) {
+ cp_plugin_info_t *plugin;
+ cp_status_t status;
+
+ if (argc != 2) {
+ /* TRANSLATORS: Usage instructios for loading a plug-in */
+ printf(_("Usage: %s <path>\n"), argv[0]);
+ } else if ((plugin = cp_load_plugin_descriptor(context, argv[1], &status)) == NULL) {
+ api_failed("cp_load_plugin_descriptor", status);
+ } else if ((status = cp_install_plugin(context, plugin)) != CP_OK) {
+ api_failed("cp_install_plugin", status);
+ cp_release_info(context, plugin);
+ } else {
+ printf(_("Installed plug-in %s.\n"), plugin->identifier);
+ cp_release_info(context, plugin);
+ }
+}
+
+static void cmd_scan_plugins(int argc, char *argv[]) {
+ int flags = 0;
+ cp_status_t status;
+ int i;
+
+ // Set flags
+ for (i = 1; i < argc; i++) {
+ int j;
+
+ for (j = 0; load_flags[j].name != NULL; j++) {
+ if (!strcmp(argv[i], load_flags[j].name)) {
+ flags |= load_flags[j].value;
+ break;
+ }
+ }
+ if (load_flags[j].name == NULL) {
+ printf(_("Unknown flag %s.\n"), argv[i]);
+ /* TRANSLATORS: Usage instructions for scanning plug-ins */
+ printf(_("Usage: %s [<flag>...]\n"), argv[0]);
+ fputs(_("Available flags are:\n"), stdout);
+ for (j = 0; load_flags[j].name != NULL; j++) {
+ printf(" %s - %s\n", load_flags[j].name, _(load_flags[j].description));
+ }
+ return;
+ }
+ }
+
+ if ((status = cp_scan_plugins(context, flags)) != CP_OK) {
+ api_failed("cp_scan_plugins", status);
+ return;
+ }
+ fputs(_("Plug-ins loaded.\n"), stdout);
+}
+
+static char *state_to_string(cp_plugin_state_t state) {
+ switch (state) {
+ case CP_PLUGIN_UNINSTALLED:
+ return _("uninstalled");
+ case CP_PLUGIN_INSTALLED:
+ return _("installed");
+ case CP_PLUGIN_RESOLVED:
+ return _("resolved");
+ case CP_PLUGIN_STARTING:
+ return _("starting");
+ case CP_PLUGIN_STOPPING:
+ return _("stopping");
+ case CP_PLUGIN_ACTIVE:
+ return _("active");
+ default:
+ return _("unknown");
+ }
+}
+
+static void cmd_list_plugins(int argc, char *argv[]) {
+ cp_plugin_info_t **plugins;
+ cp_status_t status;
+ int i;
+
+ if (argc != 1) {
+ /* TRANSLATORS: Usage instructions for listing plug-ins */
+ printf(_("Usage: %s\n"), argv[0]);
+ } else if ((plugins = cp_get_plugins_info(context, &status, NULL)) == NULL) {
+ api_failed("cp_get_plugins_info", status);
+ } else {
+ const char format[] = " %-24s %-8s %-12s %s %-20s\n";
+ fputs(_("Installed plug-ins:\n"), stdout);
+ printf(format,
+ _("IDENTIFIER"),
+ _("VERSION"),
+ _("STATE"),
+ _("NAME"),
+ _("URL"));
+ for (i = 0; plugins[i] != NULL; i++) {
+ printf(format,
+ plugins[i]->identifier,
+ plugins[i]->version != NULL ? plugins[i]->version : "",
+ state_to_string(cp_get_plugin_state(context, plugins[i]->identifier)),
+ plugins[i]->name != NULL ? plugins[i]->name : "",plugins[i]->url != NULL ? plugins[i]->url : "");
+ }
+ cp_release_info(context, plugins);
+ }
+}
+
+struct str_list_entry_t {
+ char *str;
+ struct str_list_entry_t *next;
+};
+
+static struct str_list_entry_t *str_list = NULL;
+
+static char *str_or_null(const char *str) {
+ if (str != NULL) {
+ char *s = malloc((strlen(str) + 3) * sizeof(char));
+ struct str_list_entry_t *entry = malloc(sizeof(struct str_list_entry_t));
+ if (s == NULL || entry == NULL) {
+ fputs(_("Memory allocation failed.\n"), stderr);
+ abort();
+ }
+ sprintf(s, "\"%s\"", str);
+ entry->next = str_list;
+ entry->str = s;
+ str_list = entry;
+ return s;
+ } else {
+ return "NULL";
+ }
+}
+
+static void str_or_null_free(void) {
+ while (str_list != NULL) {
+ struct str_list_entry_t *next = str_list->next;
+ free(str_list->str);
+ free(str_list);
+ str_list = next;
+ }
+}
+
+static void show_plugin_info_import(cp_plugin_import_t *import) {
+ printf(" plugin_id = \"%s\",\n"
+ " version = %s,\n"
+ " optional = %d,\n",
+ import->plugin_id,
+ str_or_null(import->version),
+ import->optional);
+}
+
+static void show_plugin_info_ext_point(cp_ext_point_t *ep) {
+ assert(ep->plugin != NULL);
+ printf(" local_id = \"%s\",\n"
+ " identifier = \"%s\",\n"
+ " name = %s,\n"
+ " schema_path = %s,\n",
+ ep->local_id,
+ ep->identifier,
+ str_or_null(ep->name),
+ str_or_null(ep->schema_path));
+}
+
+static void strcat_quote_xml(char *dst, const char *src, int is_attr) {
+ char c;
+
+ while (*dst != '\0')
+ dst++;
+ do {
+ switch ((c = *(src++))) {
+ case '&':
+ strcpy(dst, "&amp;");
+ dst += 5;
+ break;
+ case '<':
+ strcpy(dst, "&lt;");
+ dst += 4;
+ break;
+ case '>':
+ strcpy(dst, "&gt;");
+ dst += 4;
+ break;
+ case '"':
+ if (is_attr) {
+ strcpy(dst, "&quot;");
+ dst += 6;
+ break;
+ }
+ default:
+ *(dst++) = c;
+ break;
+ }
+ } while (c != '\0');
+}
+
+static int strlen_quoted_xml(const char *str,int is_attr) {
+ int len = 0;
+ int i;
+
+ for (i = 0; str[i] != '\0'; i++) {
+ switch (str[i]) {
+ case '&':
+ len += 5;
+ break;
+ case '<':
+ case '>':
+ len += 4;
+ break;
+ case '"':
+ if (is_attr) {
+ len += 6;
+ break;
+ }
+ default:
+ len++;
+ }
+ }
+ return len;
+}
+
+static void show_plugin_info_cfg(cp_cfg_element_t *ce, int indent) {
+ char *buffer = NULL;
+ int rs;
+ int i;
+
+ // Calculate the maximum required buffer size
+ rs = 2 * strlen(ce->name) + 6 + indent;
+ if (ce->value != NULL) {
+ rs += strlen_quoted_xml(ce->value, 0);
+ }
+ for (i = 0; i < ce->num_atts; i++) {
+ rs += strlen(ce->atts[2*i]);
+ rs += strlen_quoted_xml(ce->atts[2*i + 1], 1);
+ rs += 4;
+ }
+
+ // Allocate buffer
+ if ((buffer = malloc(rs * sizeof(char))) == NULL) {
+ fputs(_("Memory allocation failed.\n"), stderr);
+ abort();
+ }
+
+ // Create the string
+ for (i = 0; i < indent; i++) {
+ buffer[i] = ' ';
+ }
+ buffer[i++] = '<';
+ buffer[i] = '\0';
+ strcat(buffer, ce->name);
+ for (i = 0; i < ce->num_atts; i++) {
+ strcat(buffer, " ");
+ strcat(buffer, ce->atts[2*i]);
+ strcat(buffer, "=\"");
+ strcat_quote_xml(buffer, ce->atts[2*i + 1], 1);
+ strcat(buffer, "\"");
+ }
+ if (ce->value != NULL || ce->num_children) {
+ strcat(buffer, ">");
+ if (ce->value != NULL) {
+ strcat_quote_xml(buffer, ce->value, 0);
+ }
+ if (ce->num_children) {
+ fputs(buffer, stdout);
+ putchar('\n');
+ for (i = 0; i < ce->num_children; i++) {
+ show_plugin_info_cfg(ce->children + i, indent + 2);
+ }
+ for (i = 0; i < indent; i++) {
+ buffer[i] = ' ';
+ }
+ buffer[i++] = '<';
+ buffer[i++] = '/';
+ buffer[i] = '\0';
+ strcat(buffer, ce->name);
+ strcat(buffer, ">");
+ } else {
+ strcat(buffer, "</");
+ strcat(buffer, ce->name);
+ strcat(buffer, ">");
+ }
+ } else {
+ strcat(buffer, "/>");
+ }
+ fputs(buffer, stdout);
+ putchar('\n');
+ free(buffer);
+}
+
+static void show_plugin_info_extension(cp_extension_t *e) {
+ assert(e->plugin != NULL);
+ printf(" ext_point_id = \"%s\",\n"
+ " local_id = %s,\n"
+ " identifier = %s,\n"
+ " name = %s,\n"
+ " configuration = {\n",
+ e->ext_point_id,
+ str_or_null(e->local_id),
+ str_or_null(e->identifier),
+ str_or_null(e->name));
+ show_plugin_info_cfg(e->configuration, 6);
+ fputs(" },\n", stdout);
+}
+
+static void cmd_show_plugin_info(int argc, char *argv[]) {
+ cp_plugin_info_t *plugin;
+ cp_status_t status;
+ int i;
+
+ if (argc != 2) {
+ /* TRANSLATORS: Usage instructions for showing plug-in information */
+ printf(_("Usage: %s <plugin>\n"), argv[0]);
+ } else if ((plugin = cp_get_plugin_info(context, argv[1], &status)) == NULL) {
+ api_failed("cp_get_plugin_info", status);
+ } else {
+ printf("{\n"
+ " identifier = \"%s\",\n"
+ " name = %s,\n"
+ " version = %s,\n"
+ " provider_name = %s,\n"
+ " abi_bw_compatibility = %s,\n"
+ " api_bw_compatibility = %s,\n"
+ " plugin_path = %s,\n"
+ " req_cpluff_version = %s,\n",
+ plugin->identifier,
+ str_or_null(plugin->name),
+ str_or_null(plugin->version),
+ str_or_null(plugin->provider_name),
+ str_or_null(plugin->abi_bw_compatibility),
+ str_or_null(plugin->api_bw_compatibility),
+ str_or_null(plugin->plugin_path),
+ str_or_null(plugin->req_cpluff_version));
+ if (plugin->num_imports) {
+ fputs(" imports = {{\n", stdout);
+ for (i = 0; i < plugin->num_imports; i++) {
+ if (i)
+ fputs(" }, {\n", stdout);
+ show_plugin_info_import(plugin->imports + i);
+ }
+ fputs(" }},\n", stdout);
+ } else {
+ fputs(" imports = {},\n", stdout);
+ }
+ printf(" runtime_lib_name = %s,\n"
+ " runtime_funcs_symbol = %s,\n",
+ str_or_null(plugin->runtime_lib_name),
+ str_or_null(plugin->runtime_funcs_symbol));
+ if (plugin->num_ext_points) {
+ fputs(" ext_points = {{\n", stdout);
+ for (i = 0; i < plugin->num_ext_points; i++) {
+ if (i)
+ fputs(" }, {\n", stdout);
+ show_plugin_info_ext_point(plugin->ext_points + i);
+ }
+ fputs(" }},\n", stdout);
+ } else {
+ fputs(" ext_points = {},\n", stdout);
+ }
+ if (plugin->num_extensions) {
+ fputs(" extensions = {{\n", stdout);
+ for (i = 0; i < plugin->num_extensions; i++) {
+ if (i)
+ fputs(" }, {\n", stdout);
+ show_plugin_info_extension(plugin->extensions + i);
+ }
+ fputs(" }}\n", stdout);
+ } else {
+ fputs(" extensions = {},\n", stdout);
+ }
+ fputs("}\n", stdout);
+ cp_release_info(context, plugin);
+ str_or_null_free();
+ }
+}
+
+static void cmd_list_ext_points(int argc, char *argv[]) {
+ cp_ext_point_t **ext_points;
+ cp_status_t status;
+ int i;
+
+ if (argc != 1) {
+ /* TRANSLATORS: Usage instructions for listing extension points */
+ printf(_("Usage: %s\n"), argv[0]);
+ } else if ((ext_points = cp_get_ext_points_info(context, &status, NULL)) == NULL) {
+ api_failed("cp_get_ext_points_info", status);
+ } else {
+ const char format[] = " %-32s %s\n";
+ fputs(_("Installed extension points:\n"), stdout);
+ printf(format,
+ _("IDENTIFIER"),
+ _("NAME"));
+ for (i = 0; ext_points[i] != NULL; i++) {
+ printf(format,
+ ext_points[i]->identifier,
+ ext_points[i]->name != NULL ? ext_points[i]->name : "");
+ }
+ cp_release_info(context, ext_points);
+ }
+}
+
+static void cmd_findResourcebyType(int argc, char *argv[]){
+ printf("cmd_findResourcebyType\n");
+ load(argv[1], context);
+}
+
+static void cmd_list_extensions(int argc, char *argv[]) {
+ cp_extension_t **extensions;
+ cp_status_t status;
+ int i;
+
+ if (argc != 1) {
+ /* TRANSLATORS: Usage instructions for listing extensions */
+ printf(_("Usage: %s\n"), argv[0]);
+ } else if ((extensions = cp_get_extensions_info(context, NULL, &status, NULL)) == NULL) {
+ api_failed("cp_get_extensions_info", status);
+ } else {
+ const char format[] = " %-32s %s\n";
+ fputs(_("Installed extensions:\n"), stdout);
+ printf(format,
+ _("IDENTIFIER"),
+ _("NAME"));
+ for (i = 0; extensions[i] != NULL; i++) {
+ if (extensions[i]->identifier == NULL) {
+ char buffer[128];
+ snprintf(buffer, sizeof(buffer), "%s%s", extensions[i]->plugin->identifier, _(".<anonymous>"));
+ strcpy(buffer + sizeof(buffer)/sizeof(char) - 4, "...");
+ printf(format,
+ buffer,
+ extensions[i]->name != NULL ? extensions[i]->name : "");
+ } else {
+ printf(format,
+ extensions[i]->identifier,
+ extensions[i]->name != NULL ? extensions[i]->name : "");
+ }
+ }
+ cp_release_info(context, extensions);
+ }
+}
+
+static char **argv_dup(int argc, char *argv[]) {
+ char **dup;
+ int i;
+
+ if ((dup = malloc((argc + 1) * sizeof(char *))) == NULL) {
+ return NULL;
+ }
+ dup[0] = "";
+ for (i = 1; i < argc; i++) {
+ if ((dup[i] = strdup(argv[i])) == NULL) {
+ for (i--; i > 0; i--) {
+ free(dup[i]);
+ }
+ free(dup);
+ return NULL;
+ }
+ }
+ dup[argc] = NULL;
+ return dup;
+}
+
+static void cmd_set_context_args(int argc, char *argv[]) {
+ char **ctx_argv;
+
+ if (argc != 1) {
+ /* TRANSLATORS: Usage instructions for setting context arguments */
+ printf(_("Usage: %s [<arg>...]\n"), argv[0]);
+ } else if ((ctx_argv = argv_dup(argc, argv)) == NULL) {
+ fputs(_("Memory allocation failed.\n"), stderr);
+ } else {
+ cp_set_context_args(context, ctx_argv);
+ fputs(_("Plug-in context startup arguments have been set.\n"), stdout);
+ }
+}
+
+static void cmd_start_plugin(int argc, char *argv[]) {
+ cp_status_t status;
+
+ if (argc != 2) {
+ /* TRANSLATORS: Usage instructions for starting a plug-in */
+ printf(_("Usage: %s <plugin>\n"), argv[0]);
+ } else if ((status = cp_start_plugin(context, argv[1])) != CP_OK) {
+ api_failed("cp_start_plugin", status);
+ } else {
+ printf(_("Started plug-in %s.\n"), argv[1]);
+ }
+}
+
+static void cmd_run_plugins_step(int argc, char *argv[]) {
+
+ if (argc != 1) {
+ /* TRANSLATORS: Usage instructions for running one plug-in run function */
+ printf(_("Usage: %s\n"), argv[0]);
+ } else {
+ int pending = cp_run_plugins_step(context);
+ if (pending) {
+ fputs(_("Ran one plug-in run function. There are pending run functions.\n"), stdout);
+ } else {
+ fputs(_("Ran one plug-in run function. No more pending run functions.\n"), stdout);
+ }
+ }
+}
+
+static void cmd_run_plugins(int argc, char *argv[]) {
+ if (argc != 1) {
+ /* TRANSLATORS: Usage instructions for running plug-in run functions until all work is done */
+ printf(_("Usage: %s\n"), argv[0]);
+ } else {
+ cp_run_plugins(context);
+ fputs(_("Ran plug-in run functions. No more pending run functions.\n"), stdout);
+ }
+}
+
+static void cmd_stop_plugin(int argc, char *argv[]) {
+ cp_status_t status;
+
+ if (argc != 2) {
+ /* TRANSLATORS: Usage instructions for stopping a plug-in */
+ printf(_("Usage: %s <plugin>\n"), argv[0]);
+ } else if ((status = cp_stop_plugin(context, argv[1])) != CP_OK) {
+ api_failed("cp_stop_plugin", status);
+ } else {
+ printf(_("Stopped plug-in %s.\n"), argv[1]);
+ }
+}
+
+static void cmd_stop_plugins(int argc, char *argv[]) {
+ if (argc != 1) {
+ /* TRANSLATORS: Usage instructions for stopping all plug-ins */
+ printf(_("Usage: %s\n"), argv[0]);
+ } else {
+ cp_stop_plugins(context);
+ fputs(_("Stopped all plug-ins.\n"), stdout);
+ }
+}
+
+static void cmd_uninstall_plugin(int argc, char *argv[]) {
+ cp_status_t status;
+
+ if (argc != 2) {
+ /* TRANSLATORS: Usage instructions for uninstalling a plug-in */
+ printf(_("Usage: %s <plugin>\n"), argv[0]);
+ } else if ((status = cp_uninstall_plugin(context, argv[1])) != CP_OK) {
+ api_failed("cp_uninstall_plugin", status);
+ } else {
+ printf(_("Uninstalled plug-in %s.\n"), argv[1]);
+ }
+}
+
+static void cmd_uninstall_plugins(int argc, char *argv[]) {
+ if (argc != 1) {
+ /* TRANSLATORS: Usage instructions for uninstalling all plug-ins */
+ printf(_("Usage: %s\n"), argv[0]);
+ } else {
+ cp_uninstall_plugins(context);
+ fputs(_("Uninstalled all plug-ins.\n"), stdout);
+ }
+}
+
+int main(int argc, char *argv[]) {
+ char *prompt;
+ int i;
+ cp_status_t status;
+
+ // Set locale
+#ifdef HAVE_GETTEXT
+ setlocale(LC_ALL, "");
+#endif
+
+ // Initialize C-Pluff library
+ if ((status = cp_init()) != CP_OK) {
+ api_failed("cp_init", status);
+ exit(1);
+ }
+
+ // Set gettext domain
+#ifdef HAVE_GETTEXT
+ textdomain(PACKAGE);
+#endif
+
+ // Display startup information
+ printf(
+ /* TRANSLATORS: This is a version string displayed on startup. */
+ _("C-Pluff Console, version %s\n"), PACKAGE_VERSION);
+ printf(
+ /* TRANSLATORS: This is a version string displayed on startup.
+ The first %s is version and the second %s is platform type. */
+ _("C-Pluff Library, version %s for %s\n"),
+ cp_get_version(), cp_get_host_type());
+
+ // Create a plug-in context
+ context = cp_create_context(&status);
+ if (context == NULL) {
+ api_failed("cp_create_context", status);
+ exit(1);
+ }
+
+ // Initialize logging
+ cp_register_logger(context, logger, NULL, log_levels[1].level);
+ printf(_("Using display log level %s (%s).\n"), log_levels[1].name, _(log_levels[1].description));
+
+ // Command line loop
+ fputs(_("Type \"help\" for help on available commands.\n"), stdout);
+ cmdline_init();
+
+ /* TRANSLATORS: This is the input prompt for cpluff-console. */
+ prompt = _("C-Pluff Console > ");
+
+ while (1) {
+ char *cmdline;
+ int argc;
+ char **argv;
+
+ // Get command line
+ cmdline = cmdline_input(prompt);
+ if (cmdline == NULL) {
+ putchar('\n');
+ cmdline = "exit";
+ }
+
+ // Parse command line
+ argc = cmdline_parse(cmdline, &argv);
+ if (argc <= 0) {
+ continue;
+ }
+
+ // Choose command
+ for (i = 0; commands[i].name != NULL; i++) {
+ if (!strcmp(argv[0], commands[i].name)) {
+ commands[i].implementation(argc, argv);
+ break;
+ }
+ }
+ if (commands[i].name == NULL) {
+ printf(_("Unknown command %s.\n"), argv[0]);
+ }
+ }
+}
diff --git a/service/protocol-plugin/lib/cpluff/console/console.h b/service/protocol-plugin/lib/cpluff/console/console.h
new file mode 100644
index 000000000..85df3c246
--- /dev/null
+++ b/service/protocol-plugin/lib/cpluff/console/console.h
@@ -0,0 +1,176 @@
+/*-------------------------------------------------------------------------
+ * C-Pluff, a plug-in framework for C
+ * Copyright 2007 Johannes Lehtinen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *-----------------------------------------------------------------------*/
+
+// Global declarations
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef HAVE_GETTEXT
+#include <libintl.h>
+#endif
+#include <cpluff.h>
+#include "PluginManager.c"
+
+
+/* ------------------------------------------------------------------------
+ * Defines
+ * ----------------------------------------------------------------------*/
+
+// Gettext defines
+#ifdef HAVE_GETTEXT
+#define _(String) gettext(String)
+#define gettext_noop(String) String
+#define N_(String) gettext_noop(String)
+#else
+#define _(String) (String)
+#define N_(String) String
+#define textdomain(Domain)
+#define bindtextdomain(Package, Directory)
+#endif
+
+
+/* ------------------------------------------------------------------------
+ * Data types
+ * ----------------------------------------------------------------------*/
+
+/// Type of argument completion
+typedef enum arg_compl_t
+{
+
+ /// Do not use completion
+ CPC_COMPL_NONE,
+
+ /// Use file name completion
+ CPC_COMPL_FILE,
+
+ /// Use scan flag completion
+ CPC_COMPL_FLAG,
+
+ /// Use log level completion
+ CPC_COMPL_LOG_LEVEL,
+
+ /// Use plug-in identifier completion
+ CPC_COMPL_PLUGIN,
+
+} arg_compl_t;
+
+/// Type for command implementations
+typedef void (*command_func_t)(int argc, char *argv[]);
+
+/// Type for command information
+typedef struct command_info_t
+{
+
+ /// The name of the command
+ char *name;
+
+ /// The description for the command
+ const char *description;
+
+ /// The command implementation
+ command_func_t implementation;
+
+ /// The type of argument completion to use
+ arg_compl_t arg_completion;
+
+} command_info_t;
+
+/// Type for flag information
+typedef struct flag_info_t
+{
+
+ /// The name of the flag
+ const char *name;
+
+ /// The description of the flag
+ const char *description;
+
+ /// The value of the flag
+ int value;
+
+} flag_info_t;
+
+/// Type for log level information
+typedef struct log_level_info_t
+{
+
+ /// The name of the log level
+ const char *name;
+
+ /// The descriptor of the log level
+ const char *description;
+
+ /// The value of the log level
+ int level;
+
+} log_level_info_t;
+
+
+/* ------------------------------------------------------------------------
+ * Global variables
+ * ----------------------------------------------------------------------*/
+
+/// The plug-in context
+CP_HIDDEN extern cp_context_t *context;
+
+/// The available commands
+CP_HIDDEN extern const command_info_t commands[];
+
+/// The available load flags
+CP_HIDDEN extern const flag_info_t load_flags[];
+
+/// The available logging levels
+CP_HIDDEN extern const log_level_info_t log_levels[];
+
+
+/* ------------------------------------------------------------------------
+ * Function declarations
+ * ----------------------------------------------------------------------*/
+
+/**
+ * Initializes command line reading. Must be called once to initialize
+ * everything before using cmdline_input.
+ */
+CP_HIDDEN void cmdline_init(void);
+
+/**
+ * Returns a command line entered by the user. Uses the specified prompt.
+ * The returned command line is valid and it may be modified until the
+ * next call to this function.
+ *
+ * @param prompt the prompt to be used
+ * @return the command line entered by the user
+ */
+CP_HIDDEN char *cmdline_input(const char *prompt);
+
+/**
+ * Releases command line reading resources. Must be called after command
+ * line input is not needed and before destroying the context.
+ */
+CP_HIDDEN void cmdline_destroy(void);
+
+#ifndef CONSOLE_H_
+#define CONSOLE_H_
+
+#endif //CONSOLE_H_