Skip to content

Commit

Permalink
namespace: convert to use subcmd
Browse files Browse the repository at this point in the history
This means we get -commands and usage via -help

Signed-off-by: Steve Bennett <[email protected]>
  • Loading branch information
msteveb committed Jul 4, 2023
1 parent b440122 commit e127e4b
Showing 1 changed file with 119 additions and 110 deletions.
229 changes: 119 additions & 110 deletions jim-namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,130 +196,139 @@ static int Jim_EvalEnsemble(Jim_Interp *interp, const char *basecmd, const char

static int JimNamespaceCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Jim_Obj *nsObj;
Jim_Obj *objPtr;
int option;
static const char * const options[] = {
"eval", "current", "canonical", "qualifiers", "parent", "tail", "delete",
"origin", "code", "inscope", "ensemble", "import", "export",
"which", "upvar", NULL
/* Must be kept in order with the array below */
enum {
OPT_CANONICAL,
OPT_CODE,
OPT_CURRENT,
OPT_DELETE,
OPT_ENSEMBLE,
OPT_EVAL,
OPT_EXPORT,
OPT_IMPORT,
OPT_INSCOPE,
OPT_ORIGIN,
OPT_PARENT,
OPT_QUALIFIERS,
OPT_TAIL,
OPT_UPVAR,
OPT_WHICH,
OPT_COUNT,
};
enum
{
OPT_EVAL, OPT_CURRENT, OPT_CANONICAL, OPT_QUALIFIERS, OPT_PARENT, OPT_TAIL, OPT_DELETE,
OPT_ORIGIN, OPT_CODE, OPT_INSCOPE, OPT_ENSEMBLE, OPT_IMPORT, OPT_EXPORT,
OPT_WHICH, OPT_UPVAR,
static const jim_subcmd_type namespace_cmds[OPT_COUNT + 1] = {
JIM_DEF_SUBCMD("canonical", "?current? ?name?", 0, 2),
JIM_DEF_SUBCMD("code", "arg", 1, 1),
JIM_DEF_SUBCMD("current", NULL, 0, 0),
JIM_DEF_SUBCMD("delete", "?name ...?", 0, -1),
JIM_DEF_SUBCMD("ensemble", "subcommand ?arg ...?", 1, -1),
JIM_DEF_SUBCMD("eval", "name arg ?arg ...?", 2, -1),
JIM_DEF_SUBCMD("export", "?...?", 0, -1),
JIM_DEF_SUBCMD("import", "?...?", 0, -1),
JIM_DEF_SUBCMD("inscope", "name arg ?arg ...?", 2, -1),
JIM_DEF_SUBCMD("origin", "name", 1, 1),
JIM_DEF_SUBCMD("parent", "?name?", 0, 1),
JIM_DEF_SUBCMD("qualifiers", "string", 1, 1),
JIM_DEF_SUBCMD("tail", "string", 1, 1),
JIM_DEF_SUBCMD("upvar", "ns ?arg ...?", 1, -1),
JIM_DEF_SUBCMD("which", "?-command|-variable? name", 1, 2),
{ /* null terminator */ }
};
const jim_subcmd_type *ct = Jim_ParseSubCmd(interp, namespace_cmds, argc, argv);
if (ct) {
if (ct->function) {
/* This is -help */
return ct->function(interp, argc, argv);
}

if (argc < 2) {
Jim_WrongNumArgs(interp, 1, argv, "subcommand ?arg ...?");
return JIM_ERR;
}

if (Jim_GetEnum(interp, argv[1], options, &option, "subcommand", JIM_ERRMSG | JIM_ENUM_ABBREV) != JIM_OK) {
return Jim_CheckShowCommands(interp, argv[1], options);
}

switch (option) {
case OPT_EVAL:
if (argc < 4) {
Jim_WrongNumArgs(interp, 2, argv, "name arg ?arg...?");
return JIM_ERR;
}
if (argc == 4) {
objPtr = argv[3];
}
else {
objPtr = Jim_ConcatObj(interp, argc - 3, argv + 3);
}

nsObj = JimCanonicalNamespace(interp, interp->framePtr->nsObj, argv[2]);
return Jim_EvalNamespace(interp, objPtr, nsObj);

case OPT_CURRENT:
if (argc != 2) {
Jim_WrongNumArgs(interp, 2, argv, "");
return JIM_ERR;
}
Jim_SetResult(interp, JimNamespaceCurrent(interp));
return JIM_OK;

case OPT_CANONICAL:
if (argc > 4) {
Jim_WrongNumArgs(interp, 2, argv, "?current? ?name?");
return JIM_ERR;
}
if (argc == 2) {
Jim_SetResult(interp, interp->framePtr->nsObj);
}
else if (argc == 3) {
Jim_SetResult(interp, JimCanonicalNamespace(interp, interp->framePtr->nsObj, argv[2]));
}
else {
Jim_SetResult(interp, JimCanonicalNamespace(interp, argv[2], argv[3]));
}
return JIM_OK;

case OPT_QUALIFIERS:
if (argc != 3) {
Jim_WrongNumArgs(interp, 2, argv, "string");
return JIM_ERR;
}
Jim_SetResult(interp, Jim_NamespaceQualifiers(interp, argv[2]));
return JIM_OK;

case OPT_EXPORT:
return JIM_OK;

case OPT_TAIL:
if (argc != 3) {
Jim_WrongNumArgs(interp, 2, argv, "string");
return JIM_ERR;
}
Jim_SetResult(interp, Jim_NamespaceTail(interp, argv[2]));
return JIM_OK;
/* (ct - namespace_cmds) is the index into the table */
switch (ct - namespace_cmds) {
case OPT_EVAL:
{
Jim_Obj *nsObj;
Jim_Obj *objPtr;
if (argc == 4) {
objPtr = argv[3];
}
else {
objPtr = Jim_ConcatObj(interp, argc - 3, argv + 3);
}

nsObj = JimCanonicalNamespace(interp, interp->framePtr->nsObj, argv[2]);
return Jim_EvalNamespace(interp, objPtr, nsObj);
}

case OPT_PARENT:
if (argc != 2 && argc != 3) {
Jim_WrongNumArgs(interp, 2, argv, "?name?");
return JIM_ERR;
}
else {
const char *name;
case OPT_CURRENT:
Jim_SetResult(interp, JimNamespaceCurrent(interp));
return JIM_OK;

if (argc == 3) {
objPtr = argv[2];
case OPT_CANONICAL:
if (argc == 2) {
Jim_SetResult(interp, interp->framePtr->nsObj);
}
else {
objPtr = interp->framePtr->nsObj;
else if (argc == 3) {
Jim_SetResult(interp, JimCanonicalNamespace(interp, interp->framePtr->nsObj, argv[2]));
}
if (Jim_Length(objPtr) == 0 || Jim_CompareStringImmediate(interp, objPtr, "::")) {
return JIM_OK;
else {
Jim_SetResult(interp, JimCanonicalNamespace(interp, argv[2], argv[3]));
}
objPtr = Jim_NamespaceQualifiers(interp, objPtr);
return JIM_OK;

name = Jim_String(objPtr);
case OPT_QUALIFIERS:
Jim_SetResult(interp, Jim_NamespaceQualifiers(interp, argv[2]));
return JIM_OK;

if (name[0] != ':' || name[1] != ':') {
/* Make it fully scoped */
Jim_SetResultString(interp, "::", 2);
Jim_AppendObj(interp, Jim_GetResult(interp), objPtr);
Jim_IncrRefCount(objPtr);
Jim_DecrRefCount(interp, objPtr);
case OPT_EXPORT:
return JIM_OK;

case OPT_TAIL:
if (argc != 3) {
Jim_WrongNumArgs(interp, 2, argv, "string");
return JIM_ERR;
}
else {
Jim_SetResult(interp, objPtr);
Jim_SetResult(interp, Jim_NamespaceTail(interp, argv[2]));
return JIM_OK;

case OPT_PARENT:
{
Jim_Obj *objPtr;
const char *name;

if (argc == 3) {
objPtr = argv[2];
}
else {
objPtr = interp->framePtr->nsObj;
}
if (Jim_Length(objPtr) == 0 || Jim_CompareStringImmediate(interp, objPtr, "::")) {
return JIM_OK;
}
objPtr = Jim_NamespaceQualifiers(interp, objPtr);

name = Jim_String(objPtr);

if (name[0] != ':' || name[1] != ':') {
/* Make it fully scoped */
Jim_SetResultString(interp, "::", 2);
Jim_AppendObj(interp, Jim_GetResult(interp), objPtr);
Jim_IncrRefCount(objPtr);
Jim_DecrRefCount(interp, objPtr);
}
else {
Jim_SetResult(interp, objPtr);
}
}
return JIM_OK;

default:
/* Implemented as a Tcl helper proc.
* Note that calling a proc will change the current namespace,
* so helper procs must call [uplevel namespace canon] to get the callers
* namespace.
*/
return Jim_EvalEnsemble(interp, "namespace", Jim_String(argv[1]), argc - 2, argv + 2);
}
return JIM_OK;
}

/* Implemented as a Tcl helper proc.
* Note that calling a proc will change the current namespace,
* so helper procs must call [uplevel namespace canon] to get the callers
* namespace.
*/
return Jim_EvalEnsemble(interp, "namespace", options[option], argc - 2, argv + 2);
return JIM_ERR;
}

int Jim_namespaceInit(Jim_Interp *interp)
Expand Down

0 comments on commit e127e4b

Please sign in to comment.