OSDN Git Service

Please enter the commit message for your changes. Lines starting
[eos/base.git] / util / src / TclTk / tcl8.6.12 / pkgs / itcl4.2.2 / generic / itclStubs.c
diff --git a/util/src/TclTk/tcl8.6.12/pkgs/itcl4.2.2/generic/itclStubs.c b/util/src/TclTk/tcl8.6.12/pkgs/itcl4.2.2/generic/itclStubs.c
new file mode 100644 (file)
index 0000000..f5c6e99
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * itclStubs.c --
+ *
+ *      This file contains the C-implemeted part of Itcl object-system
+ *      Itcl
+ *
+ * Copyright (c) 2006 by Arnulf P. Wiedemann
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "itclInt.h"
+
+static void ItclDeleteStub(ClientData cdata);
+static int ItclHandleStubCmd(ClientData clientData, Tcl_Interp *interp,
+        int objc, Tcl_Obj *const objv[]);
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_IsStub()
+ *
+ *  Checks the given Tcl command to see if it represents an autoloading
+ *  stub created by the "stub create" command.  Returns non-zero if
+ *  the command is indeed a stub.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_IsStub(
+    Tcl_Command cmdPtr)      /* command being tested */
+{
+    Tcl_CmdInfo cmdInfo;
+
+    /*
+     *  This may be an imported command, but don't try to get the
+     *  original.  Just check to see if this particular command
+     *  is a stub.  If we really want the original command, we'll
+     *  find it at a higher level.
+     */
+    if (Tcl_GetCommandInfoFromToken(cmdPtr, &cmdInfo) == 1) {
+        if (cmdInfo.deleteProc == ItclDeleteStub) {
+            return 1;
+        }
+    }
+    return 0;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_StubCreateCmd()
+ *
+ *  Invoked by Tcl whenever the user issues a "stub create" command to
+ *  create an autoloading stub for imported commands.  Handles the
+ *  following syntax:
+ *
+ *    stub create <name>
+ *
+ *  Creates a command called <name>.  Executing this command will cause
+ *  the real command <name> to be autoloaded.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_StubCreateCmd(
+    TCL_UNUSED(ClientData),   /* not used */
+    Tcl_Interp *interp,      /* current interpreter */
+    int objc,                /* number of arguments */
+    Tcl_Obj *const objv[])   /* argument objects */
+{
+    Tcl_Command cmdPtr;
+    char *cmdName;
+    Tcl_CmdInfo cmdInfo;
+
+    ItclShowArgs(1, "Itcl_StubCreateCmd", objc, objv);
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "name");
+        return TCL_ERROR;
+    }
+    cmdName = Tcl_GetString(objv[1]);
+
+    /*
+     *  Create a stub command with the characteristic ItclDeleteStub
+     *  procedure.  That way, we can recognize this command later
+     *  on as a stub.  Save the cmd token as client data, so we can
+     *  get the full name of this command later on.
+     */
+    cmdPtr = Tcl_CreateObjCommand(interp, cmdName,
+        ItclHandleStubCmd, NULL,
+        (Tcl_CmdDeleteProc*)ItclDeleteStub);
+
+    Tcl_GetCommandInfoFromToken(cmdPtr, &cmdInfo);
+    cmdInfo.objClientData = cmdPtr;
+    Tcl_SetCommandInfoFromToken(cmdPtr, &cmdInfo);
+
+    return TCL_OK;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  Itcl_StubExistsCmd()
+ *
+ *  Invoked by Tcl whenever the user issues a "stub exists" command to
+ *  see if an existing command is an autoloading stub.  Handles the
+ *  following syntax:
+ *
+ *    stub exists <name>
+ *
+ *  Looks for a command called <name> and checks to see if it is an
+ *  autoloading stub.  Returns a boolean result.
+ * ------------------------------------------------------------------------
+ */
+int
+Itcl_StubExistsCmd(
+    TCL_UNUSED(ClientData),   /* not used */
+    Tcl_Interp *interp,      /* current interpreter */
+    int objc,                /* number of arguments */
+    Tcl_Obj *const objv[])   /* argument objects */
+{
+    Tcl_Command cmdPtr;
+    char *cmdName;
+
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "name");
+        return TCL_ERROR;
+    }
+    cmdName = Tcl_GetString(objv[1]);
+
+    cmdPtr = Tcl_FindCommand(interp, cmdName, NULL, 0);
+
+    if ((cmdPtr != NULL) && Itcl_IsStub(cmdPtr)) {
+        Tcl_SetWideIntObj(Tcl_GetObjResult(interp), 1);
+    } else {
+        Tcl_SetWideIntObj(Tcl_GetObjResult(interp), 0);
+    }
+    return TCL_OK;
+}
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclHandleStubCmd()
+ *
+ *  Invoked by Tcl to handle commands created by "stub create".
+ *  Calls "auto_load" with the full name of the current command to
+ *  trigger autoloading of the real implementation.  Then, calls the
+ *  command to handle its function.  If successful, this command
+ *  returns TCL_OK along with the result from the real implementation
+ *  of this command.  Otherwise, it returns TCL_ERROR, along with an
+ *  error message in the interpreter.
+ * ------------------------------------------------------------------------
+ */
+static int
+ItclHandleStubCmd(
+    ClientData clientData,   /* command token for this stub */
+    Tcl_Interp *interp,      /* current interpreter */
+    int objc,                /* number of arguments */
+    Tcl_Obj *const objv[])   /* argument objects */
+{
+    Tcl_Command cmdPtr;
+    Tcl_Obj **cmdlinev;
+    Tcl_Obj *objAutoLoad[2];
+    Tcl_Obj *objPtr;
+    Tcl_Obj *cmdNamePtr;
+    Tcl_Obj *cmdlinePtr;
+    char *cmdName;
+    int result;
+    int loaded;
+    int cmdlinec;
+
+    ItclShowArgs(1, "ItclHandleStubCmd", objc, objv);
+    cmdPtr = (Tcl_Command) clientData;
+    cmdNamePtr = Tcl_NewStringObj(NULL, 0);
+    Tcl_IncrRefCount(cmdNamePtr);
+    Tcl_GetCommandFullName(interp, cmdPtr, cmdNamePtr);
+    cmdName = Tcl_GetString(cmdNamePtr);
+
+    /*
+     *  Try to autoload the real command for this stub.
+     */
+    objAutoLoad[0] = Tcl_NewStringObj("::auto_load", -1);
+    objAutoLoad[1] = cmdNamePtr;
+    result = Tcl_EvalObjv(interp, 2, objAutoLoad, 0);
+    if (result != TCL_OK) {
+        Tcl_DecrRefCount(cmdNamePtr);
+        return TCL_ERROR;
+    }
+
+    objPtr = Tcl_GetObjResult(interp);
+    result = Tcl_GetIntFromObj(interp, objPtr, &loaded);
+    if ((result != TCL_OK) || !loaded) {
+        Tcl_ResetResult(interp);
+        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
+            "can't autoload \"", cmdName, "\"", NULL);
+        Tcl_DecrRefCount(cmdNamePtr);
+        return TCL_ERROR;
+    }
+
+    /*
+     *  At this point, the real implementation has been loaded.
+     *  Invoke the command again with the arguments passed in.
+     */
+    cmdlinePtr = Itcl_CreateArgs(interp, cmdName, objc - 1, objv + 1);
+    (void) Tcl_ListObjGetElements(NULL, cmdlinePtr,
+        &cmdlinec, &cmdlinev);
+
+    Tcl_DecrRefCount(cmdNamePtr);
+    Tcl_ResetResult(interp);
+    ItclShowArgs(1, "ItclHandleStubCmd", cmdlinec - 1, cmdlinev + 1);
+    result = Tcl_EvalObjv(interp, cmdlinec - 1, cmdlinev + 1, TCL_EVAL_DIRECT);
+    Tcl_DecrRefCount(cmdlinePtr);
+    Tcl_DecrRefCount(objAutoLoad[0]);
+    return result;
+}
+
+\f
+/*
+ * ------------------------------------------------------------------------
+ *  ItclDeleteStub()
+ *
+ *  Invoked by Tcl whenever a stub command is deleted.  This procedure
+ *  does nothing, but its presence identifies a command as a stub.
+ * ------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+static void
+ItclDeleteStub(
+    TCL_UNUSED(ClientData))      /* not used */
+{
+    /* do nothing */
+}
+