aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2016-08-17 17:04:41 +1000
committerSteve Bennett <steveb@workware.net.au>2016-09-29 08:16:12 +1000
commit94357f11bcab186bbdbb291cdda0f7acf61165e9 (patch)
treee03a44487d05aabf8c52ae5e37857c66b12fee32
parent2b7bbc93323cc1ef9d67625e48b0435e1af4efbd (diff)
downloadjimtcl-94357f11bcab186bbdbb291cdda0f7acf61165e9.zip
jimtcl-94357f11bcab186bbdbb291cdda0f7acf61165e9.tar.gz
jimtcl-94357f11bcab186bbdbb291cdda0f7acf61165e9.tar.bz2
Add support for "-commands" to many commands
This option returns a list of support subcommands and is useful for command line completion. Support added to: socket, namespace, tcl::prefix, string, dict, info Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r--jim-aio.c2
-rw-r--r--jim-namespace.c2
-rw-r--r--jim-tclprefix.c2
-rw-r--r--jim.c67
-rw-r--r--jim.h2
5 files changed, 57 insertions, 18 deletions
diff --git a/jim-aio.c b/jim-aio.c
index e8af2f3..93e0b41 100644
--- a/jim-aio.c
+++ b/jim-aio.c
@@ -1679,7 +1679,7 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
if (Jim_GetEnum(interp, argv[1], socktypes, &socktype, "socket type", JIM_ERRMSG) != JIM_OK)
- return JIM_ERR;
+ return Jim_CheckShowCommands(interp, argv[1], socktypes);
Jim_SetEmptyResult(interp);
diff --git a/jim-namespace.c b/jim-namespace.c
index bcc7259..9920488 100644
--- a/jim-namespace.c
+++ b/jim-namespace.c
@@ -217,7 +217,7 @@ static int JimNamespaceCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
if (Jim_GetEnum(interp, argv[1], options, &option, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) {
- return JIM_ERR;
+ return Jim_CheckShowCommands(interp, argv[1], options);
}
switch (option) {
diff --git a/jim-tclprefix.c b/jim-tclprefix.c
index e041cc6..fd696b7 100644
--- a/jim-tclprefix.c
+++ b/jim-tclprefix.c
@@ -43,7 +43,7 @@ static int Jim_TclPrefixCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const
return JIM_ERR;
}
if (Jim_GetEnum(interp, argv[1], options, &option, NULL, JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK)
- return JIM_ERR;
+ return Jim_CheckShowCommands(interp, argv[1], options);
switch (option) {
case OPT_MATCH:{
diff --git a/jim.c b/jim.c
index f3a423e..65b434e 100644
--- a/jim.c
+++ b/jim.c
@@ -12879,7 +12879,7 @@ static int Jim_DebugCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar
return JIM_ERR;
}
if (Jim_GetEnum(interp, argv[1], options, &option, "subcommand", JIM_ERRMSG) != JIM_OK)
- return JIM_ERR;
+ return Jim_CheckShowCommands(interp, argv[1], options);
if (option == OPT_REFCOUNT) {
if (argc != 3) {
Jim_WrongNumArgs(interp, 2, argv, "object");
@@ -13631,7 +13631,7 @@ static int Jim_StringCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
}
if (Jim_GetEnum(interp, argv[1], options, &option, NULL,
JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK)
- return JIM_ERR;
+ return Jim_CheckShowCommands(interp, argv[1], options);
switch (option) {
case OPT_LENGTH:
@@ -14480,7 +14480,7 @@ static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
}
if (Jim_GetEnum(interp, argv[1], options, &option, "subcommand", JIM_ERRMSG) != JIM_OK) {
- return JIM_ERR;
+ return Jim_CheckShowCommands(interp, argv[1], options);
}
switch (option) {
@@ -14667,9 +14667,8 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
Jim_WrongNumArgs(interp, 1, argv, "subcommand ?args ...?");
return JIM_ERR;
}
- if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV)
- != JIM_OK) {
- return JIM_ERR;
+ if (Jim_GetEnum(interp, argv[1], commands, &cmd, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) {
+ return Jim_CheckShowCommands(interp, argv[1], commands);
}
/* Test for the most common commands first, just in case it makes a difference */
@@ -15544,36 +15543,74 @@ void Jim_MakeErrorMessage(Jim_Interp *interp)
Jim_EvalObjVector(interp, 2, argv);
}
-static void JimSetFailedEnumResult(Jim_Interp *interp, const char *arg, const char *badtype,
- const char *prefix, const char *const *tablePtr, const char *name)
+/*
+ * Given a null terminated array of strings, returns an allocated, sorted
+ * copy of the array.
+ */
+static char **JimSortStringTable(const char *const *tablePtr)
{
int count;
char **tablePtrSorted;
- int i;
+ /* Find the size of the table */
for (count = 0; tablePtr[count]; count++) {
}
+ /* Allocate one extra for the terminating NULL pointer */
+ tablePtrSorted = Jim_Alloc(sizeof(char *) * (count + 1));
+ memcpy(tablePtrSorted, tablePtr, sizeof(char *) * count);
+ qsort(tablePtrSorted, count, sizeof(char *), qsortCompareStringPointers);
+ tablePtrSorted[count] = NULL;
+
+ return tablePtrSorted;
+}
+
+static void JimSetFailedEnumResult(Jim_Interp *interp, const char *arg, const char *badtype,
+ const char *prefix, const char *const *tablePtr, const char *name)
+{
+ char **tablePtrSorted;
+ int i;
+
if (name == NULL) {
name = "option";
}
Jim_SetResultFormatted(interp, "%s%s \"%s\": must be ", badtype, name, arg);
- tablePtrSorted = Jim_Alloc(sizeof(char *) * count);
- memcpy(tablePtrSorted, tablePtr, sizeof(char *) * count);
- qsort(tablePtrSorted, count, sizeof(char *), qsortCompareStringPointers);
- for (i = 0; i < count; i++) {
- if (i + 1 == count && count > 1) {
+ tablePtrSorted = JimSortStringTable(tablePtr);
+ for (i = 0; tablePtrSorted[i]; i++) {
+ if (tablePtrSorted[i + 1] == NULL && i > 0) {
Jim_AppendString(interp, Jim_GetResult(interp), "or ", -1);
}
Jim_AppendStrings(interp, Jim_GetResult(interp), prefix, tablePtrSorted[i], NULL);
- if (i + 1 != count) {
+ if (tablePtrSorted[i + 1]) {
Jim_AppendString(interp, Jim_GetResult(interp), ", ", -1);
}
}
Jim_Free(tablePtrSorted);
}
+
+/*
+ * If objPtr is "-commands" sets the Jim result as a sorted list of options in the table
+ * and returns JIM_OK.
+ *
+ * Otherwise returns JIM_ERR.
+ */
+int Jim_CheckShowCommands(Jim_Interp *interp, Jim_Obj *objPtr, const char *const *tablePtr)
+{
+ if (Jim_CompareStringImmediate(interp, objPtr, "-commands")) {
+ int i;
+ char **tablePtrSorted = JimSortStringTable(tablePtr);
+ Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0));
+ for (i = 0; tablePtrSorted[i]; i++) {
+ Jim_ListAppendElement(interp, Jim_GetResult(interp), Jim_NewStringObj(interp, tablePtrSorted[i], -1));
+ }
+ Jim_Free(tablePtrSorted);
+ return JIM_OK;
+ }
+ return JIM_ERR;
+}
+
int Jim_GetEnum(Jim_Interp *interp, Jim_Obj *objPtr,
const char *const *tablePtr, int *indexPtr, const char *name, int flags)
{
diff --git a/jim.h b/jim.h
index 5c8de22..183f970 100644
--- a/jim.h
+++ b/jim.h
@@ -842,6 +842,8 @@ JIM_EXPORT void Jim_WrongNumArgs (Jim_Interp *interp, int argc,
Jim_Obj *const *argv, const char *msg);
JIM_EXPORT int Jim_GetEnum (Jim_Interp *interp, Jim_Obj *objPtr,
const char * const *tablePtr, int *indexPtr, const char *name, int flags);
+JIM_EXPORT int Jim_CheckShowCommands(Jim_Interp *interp, Jim_Obj *objPtr,
+ const char *const *tablePtr);
JIM_EXPORT int Jim_ScriptIsComplete(Jim_Interp *interp,
Jim_Obj *scriptObj, char *stateCharPtr);