diff options
Diffstat (limited to 'jim-mk.cpp')
-rw-r--r-- | jim-mk.cpp | 155 |
1 files changed, 135 insertions, 20 deletions
@@ -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; |