aboutsummaryrefslogtreecommitdiff
path: root/jim-mk.cpp
diff options
context:
space:
mode:
authorAlexander Shpilkin <ashpilkin@gmail.com>2011-08-29 20:00:37 +0400
committerSteve Bennett <steveb@workware.net.au>2011-08-31 12:15:55 +1000
commit0480a7529173a79e27b0e94d8e298aa6796ccf45 (patch)
tree662d27fa2595054baac5958bef0314933e671b8a /jim-mk.cpp
parent8f31a1072a61595f99606fe6e709c0c93fd7bbce (diff)
downloadjimtcl-0480a7529173a79e27b0e94d8e298aa6796ccf45.zip
jimtcl-0480a7529173a79e27b0e94d8e298aa6796ccf45.tar.gz
jimtcl-0480a7529173a79e27b0e94d8e298aa6796ccf45.tar.bz2
Add Ratcl-style pipelines to Metakit extension
Add pipeline support to Metakit cursors Make Metakit extension commands extensible
Diffstat (limited to 'jim-mk.cpp')
-rw-r--r--jim-mk.cpp155
1 files changed, 135 insertions, 20 deletions
diff --git a/jim-mk.cpp b/jim-mk.cpp
index b3a9515..637c2dd 100644
--- a/jim-mk.cpp
+++ b/jim-mk.cpp
@@ -42,6 +42,8 @@ static int JimToMkDescription(Jim_Interp *interp, Jim_Obj *obj, char **descrPtr)
static Jim_Obj *JimGetMkValue(Jim_Interp *interp, c4_Cursor cur, const c4_Property &prop);
static int JimSetMkValue(Jim_Interp *interp, c4_Cursor cur, const c4_Property &prop, Jim_Obj *obj);
+static int JimPipelineBoundary(int argc, Jim_Obj *const *argv);
+
/* property object */
static Jim_Obj *JimNewPropertyObj (Jim_Interp *interp, c4_Property prop);
static int JimGetProperty (Jim_Interp *interp, Jim_Obj *obj,
@@ -369,6 +371,18 @@ static int JimSetMkValue(Jim_Interp *interp, c4_Cursor cur, const c4_Property &p
}
}
+static int JimPipelineBoundary(int argc, Jim_Obj *const *argv) {
+ const char *rep;
+ int pipe, len;
+
+ for (pipe = 0; pipe < argc; pipe++) {
+ rep = Jim_GetString(argv[pipe], &len);
+ if (len == 1 && rep[0] == '|')
+ break;
+ }
+ return pipe;
+}
+
/* -------------------------------------------------------------------------
* Property object
* ------------------------------------------------------------------------- */
@@ -799,16 +813,19 @@ static int cursor_cmd_get(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
Jim_SetResult(interp, result);
+ return JIM_OK;
}
else { /* Return a single property */
const c4_Property *propPtr;
+ int pipe;
- if (argc == 2) {
+ pipe = JimPipelineBoundary(argc, argv);
+ if (pipe == 2) {
/* No type annotation, existing property */
if (JimGetProperty(interp, argv[1], view, NULL, &propPtr) != JIM_OK)
return JIM_ERR;
}
- else {
+ else if (pipe == 3) {
/* Explicit type annotation; the property may be new */
int idx;
@@ -818,11 +835,18 @@ static int cursor_cmd_get(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
if (JimGetNewProperty(interp, argv[2], view, jim_mktype_types[idx], &propPtr) != JIM_OK)
return JIM_ERR;
}
+ else {
+ Jim_WrongNumArgs(interp, 0, NULL, "cursor get ?-type? ?prop?");
+ return JIM_ERR;
+ }
Jim_SetResult(interp, JimGetMkValue(interp, cur, *propPtr));
- }
- return JIM_OK;
+ if (pipe == argc)
+ return JIM_OK;
+ else
+ return Jim_EvalObjPrefix(interp, Jim_GetResult(interp), argc - pipe - 1, argv + pipe + 1);
+ }
}
static int cursor_cmd_set(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -1085,7 +1109,7 @@ static const jim_subcmd_type cursor_command_table[] = {
{ "get", "cur ?-type? ?prop?",
cursor_cmd_get,
- 1, 3,
+ 1, -1,
0,
"Get the whole record or a specific property at the cursor"
},
@@ -1147,6 +1171,27 @@ static const jim_subcmd_type cursor_command_table[] = {
{ 0 }
};
+static int JimCursorCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ Jim_Obj *cmdObj;
+
+ if (argc < 2) {
+ Jim_WrongNumArgs(interp, 1, argv, "command ...");
+ return JIM_ERR;
+ }
+
+ cmdObj = Jim_NewStringObj(interp, "cursor ", -1);
+ Jim_AppendObj(interp, cmdObj, argv[1]);
+
+ if (Jim_GetCommand(interp, cmdObj, 0) != NULL)
+ return Jim_EvalObjPrefix(interp, cmdObj, argc - 2, argv + 2);
+ else {
+ Jim_FreeNewObj(interp, cmdObj);
+ return Jim_CallSubCmd(interp,
+ Jim_ParseSubCmd(interp, cursor_command_table, argc, argv), argc, argv);
+ }
+}
+
/* -------------------------------------------------------------------------
* View handle
* ------------------------------------------------------------------------- */
@@ -1530,8 +1575,6 @@ static int view_cmd_destroy(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
/* Command table ----------------------------------------------------------- */
-#define JIM_CMDFLAG_NODESTROY 0x0100 /* Do not destroy a one-shot view after this command */
-
static const jim_subcmd_type view_command_table[] = {
/* Unary operations */
@@ -1682,19 +1725,19 @@ static const jim_subcmd_type view_command_table[] = {
{ "pin", "",
view_cmd_pin,
0, 0,
- JIM_MODFLAG_FULLARGV | JIM_CMDFLAG_NODESTROY,
+ JIM_MODFLAG_FULLARGV,
"Marks the view as persistent"
},
{ "as", "varName",
view_cmd_as,
1, 1,
- JIM_MODFLAG_FULLARGV | JIM_CMDFLAG_NODESTROY,
+ JIM_MODFLAG_FULLARGV,
"Marks the view as persistent and assigns it to the given variable"
},
{ "destroy", "",
view_cmd_destroy,
0, 0,
- JIM_MODFLAG_FULLARGV | JIM_CMDFLAG_NODESTROY,
+ JIM_MODFLAG_FULLARGV,
"Destroys the view explicitly"
},
@@ -1708,16 +1751,59 @@ static void JimViewDelProc(Jim_Interp *interp, void *privData)
static int JimViewSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- return Jim_CallSubCmd(interp, Jim_ParseSubCmd(interp, view_command_table, argc, argv), argc, argv);
+ int pipe, result;
+ Jim_Obj *cmdObj;
+
+ pipe = JimPipelineBoundary(argc, argv);
+
+ if (pipe < 1) {
+ Jim_WrongNumArgs(interp, 1, argv, "command ...");
+ return JIM_ERR;
+ }
+
+ /* Check for a Tcl command first, and try builtins afterwards.
+ * We have to do it in this order so that Jim_ParseSubCmd isn't too greedy
+ * about abbreviations, and still it can't now detect ambigous abbrevs
+ * properly :( Tcl commands cannot be abbreviated at all.
+ */
+
+ cmdObj = Jim_NewStringObj(interp, "mk.view ", -1);
+ Jim_AppendObj(interp, cmdObj, argv[1]);
+
+ /* The command will be cached even though we discard the result */
+ if (Jim_GetCommand(interp, cmdObj, 0) != NULL) {
+ /* Shuffle the arguments: $view cmd args... => {mk.view cmd} $view args... */
+
+ Jim_Obj **objv = (Jim_Obj **)Jim_Alloc(pipe * sizeof(Jim_Obj *));
+ objv[0] = cmdObj;
+ objv[1] = argv[0];
+ memcpy(objv + 2, argv + 2, (pipe - 2) * sizeof(Jim_Obj *));
+
+ result = Jim_EvalObjVector(interp, pipe, objv);
+
+ Jim_Free(objv);
+ } else {
+ Jim_FreeNewObj(interp, cmdObj);
+ result = Jim_CallSubCmd(interp, Jim_ParseSubCmd(interp, view_command_table, pipe, argv), pipe, argv);
+ }
+
+ if (result != JIM_OK || pipe == argc)
+ return result;
+ else
+ return Jim_EvalObjPrefix(interp, Jim_GetResult(interp), argc - pipe - 1, argv + pipe + 1);
}
static int JimOneShotViewSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- const jim_subcmd_type *cmd = Jim_ParseSubCmd(interp, view_command_table, argc, argv);
- int result = Jim_CallSubCmd(interp, cmd, argc, argv);
+ int result;
+ Jim_Cmd *cmd;
- if (!cmd || !(cmd->flags & JIM_CMDFLAG_NODESTROY))
+ result = JimViewSubCmdProc(interp, argc, argv);
+
+ cmd = Jim_GetCommand(interp, argv[0], 0);
+ if (cmd && !cmd->isproc && cmd->u.native.cmdProc == JimOneShotViewSubCmdProc)
Jim_DeleteCommand(interp, Jim_String(argv[0]));
+
return result;
}
@@ -1845,9 +1931,18 @@ static int storage_cmd_view(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
if (JimGetProperty(interp, argv[0], mk->storage, "view", &propPtr) != JIM_OK)
return JIM_ERR;
-
Jim_SetResult(interp, JimGetMkValue(interp, mk->content, *propPtr));
- return JIM_OK;
+
+ if (argc == 1)
+ return JIM_OK;
+ else {
+ if (!Jim_CompareStringImmediate(interp, argv[1], "|")) {
+ Jim_SetResultFormatted(interp,
+ "expected start of a pipeline but got \"%#s\"", argv[1]);
+ return JIM_ERR;
+ }
+ return Jim_EvalObjPrefix(interp, Jim_GetResult(interp), argc - 2, argv + 2);
+ }
}
static int storage_cmd_structure(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -1976,7 +2071,7 @@ static const jim_subcmd_type storage_command_table[] = {
},
{ "view", "viewName",
storage_cmd_view,
- 1, 1,
+ 1, -1,
0,
"Retrieve the view specified by viewName"
},
@@ -2023,8 +2118,28 @@ static void JimStorageDelProc(Jim_Interp *interp, void *privData)
static int JimStorageSubCmdProc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- return Jim_CallSubCmd(interp, Jim_ParseSubCmd(interp,
- storage_command_table, argc, argv), argc, argv);
+ Jim_Obj *cmdObj;
+
+ cmdObj = Jim_NewStringObj(interp, "mk.storage ", -1);
+ Jim_AppendObj(interp, cmdObj, argv[1]);
+
+ if (Jim_GetCommand(interp, cmdObj, 0) != NULL) {
+ int result;
+
+ Jim_Obj **objv = (Jim_Obj **)Jim_Alloc(argc * sizeof(Jim_Obj *));
+ objv[0] = cmdObj;
+ objv[1] = argv[0];
+ memcpy(objv + 2, argv + 2, (argc - 2) * sizeof(Jim_Obj *));
+
+ result = Jim_EvalObjVector(interp, argc, objv);
+
+ Jim_Free(objv);
+ return result;
+ } else {
+ Jim_FreeNewObj(interp, cmdObj);
+ return Jim_CallSubCmd(interp, Jim_ParseSubCmd(interp,
+ storage_command_table, argc, argv), argc, argv);
+ }
}
/* -------------------------------------------------------------------------
@@ -2153,7 +2268,7 @@ int Jim_mkInit(Jim_Interp *interp)
return JIM_ERR;
Jim_CreateCommand(interp, "storage", JimStorageCommand, NULL, NULL);
- Jim_CreateCommand(interp, "cursor", Jim_SubCmdProc, (void *)cursor_command_table, NULL);
+ Jim_CreateCommand(interp, "cursor", JimCursorCommand, NULL, NULL);
Jim_CreateCommand(interp, "mk.view.finalizer", JimViewFinalizerProc, NULL, NULL);
return JIM_OK;