diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2013-04-03 21:24:39 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2013-04-03 21:24:39 (GMT) |
commit | 5821b2fb6d32fc0b83f7b88b10066a47de94a7df (patch) | |
tree | e479818aa2b7f9aa45d4d5954b6f1c8b4d37eff6 | |
parent | 63dd224af5885144ab5a1de8919c5e8ea9d4b969 (diff) | |
parent | f71425f1ea687ee9529bfd4fbff606ef58a09dc5 (diff) | |
download | tcl-5821b2fb6d32fc0b83f7b88b10066a47de94a7df.zip tcl-5821b2fb6d32fc0b83f7b88b10066a47de94a7df.tar.gz tcl-5821b2fb6d32fc0b83f7b88b10066a47de94a7df.tar.bz2 |
rebase
-rw-r--r-- | doc/InitSubSyst.3 | 53 | ||||
-rw-r--r-- | generic/tcl.h | 12 | ||||
-rw-r--r-- | generic/tclEncoding.c | 36 | ||||
-rw-r--r-- | generic/tclMain.c | 2 | ||||
-rw-r--r-- | generic/tclStubLib.c | 55 |
5 files changed, 128 insertions, 30 deletions
diff --git a/doc/InitSubSyst.3 b/doc/InitSubSyst.3 new file mode 100644 index 0000000..08b3154 --- /dev/null +++ b/doc/InitSubSyst.3 @@ -0,0 +1,53 @@ +'\" +'\" Copyright (c) 2013 Tcl Core Team +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +.so man.macros +.TH Tcl_InitSubsystems 3 8.6.1 Tcl "Tcl Library Procedures" +.BS +.SH NAME +Tcl_InitSubsystems \- initialize the Tcl library. +.SH SYNOPSIS +.nf +\fB#include <tcl.h>\fR +.sp +const char * +\fBTcl_InitSubsystems\fR(\fIpanicProc\fR) +.SH ARGUMENTS +.SH ARGUMENTS +.AS Tcl_PanicProc *panicProc +.AP Tcl_PanicProc *panicProc in +Desired panic function, for error reporting. If NULL, the default +panicProc is used, which normally writes the message to stderr. +.BE + +.SH DESCRIPTION +.PP +The \fBTcl_InitSubsystems\fR procedure initializes the Tcl +library. This procedure is typically invoked as the very +first thing in the application's main program. +.PP +\fBTcl_InitSubsystems\fR is very similar in use to +\fBTcl_FindExecutable\fR. It can be used when Tcl is +used as utility library, no other encodings than utf8, +iso8859-1 or unicode are used, and no interest exists in the +value of \fBinfo nameofexecutable\fR. The system encoding will not +be extracted from the environment, but falls back to iso8859-1. +.PP +The return value is the Tcl version. +.PP +If \fBTcl_InitSubsystems()\fR is called in code where +\fBUSE_TCL_STUBS\fR is set, it does one additional thing: +initialize the Stub table for using Tcl as utility +library, without needing a Tcl interpreter. For example: +.CS +const char *version = Tcl_InitSubSystems(NULL); +/* At this point, Tcl C API calls without interp are ready for use */ +int major, minor, patch; +Tcl_GetVersion(&major, &minor, &patch); +.CE +This will work as expected, both with and without stubs. +.SH KEYWORDS +binary, executable file diff --git a/generic/tcl.h b/generic/tcl.h index 4de18f0..543b2a6 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -2409,13 +2409,23 @@ const char * TclTomMathInitializeStubs(Tcl_Interp *interp, * TODO - tommath stubs export goes here! */ +/* Tcl_InitSubsystems, see TIP #414 */ + +#ifdef USE_TCL_STUBS +EXTERN Tcl_Interp *Tcl_InitSubsystems(Tcl_PanicProc *panicProc); +#define Tcl_InitSubsystems(panicProc) \ + Tcl_InitStubs((Tcl_InitSubsystems)(panicProc), NULL, 0) +#else +EXTERN const char *Tcl_InitSubsystems(Tcl_PanicProc *panicProc); +#endif + /* * Public functions that are not accessible via the stubs table. * Tcl_GetMemoryInfo is needed for AOLserver. [Bug 1868171] */ #define Tcl_Main(argc, argv, proc) Tcl_MainEx(argc, argv, proc, \ - (Tcl_FindExecutable(argv[0]), (Tcl_CreateInterp)())) + (Tcl_InitSubsystems(NULL), Tcl_CreateInterp())) EXTERN void Tcl_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); EXTERN const char * Tcl_PkgInitStubsCheck(Tcl_Interp *interp, diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 2cc55d6..a83a6b0 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -1411,21 +1411,49 @@ Tcl_UtfToExternal( /* *--------------------------------------------------------------------------- * - * Tcl_FindExecutable -- + * Tcl_InitSubsystems/Tcl_FindExecutable -- * - * This function computes the absolute path name of the current - * application, given its argv[0] value. + * This function initializes everything needed for the Tcl library + * to be able to operate. * * Results: * None. * * Side effects: * The absolute pathname for the application is computed and stored to be - * returned later be [info nameofexecutable]. + * returned later by [info nameofexecutable]. The system encoding is + * determined and stored to be returned later by [encoding system] * *--------------------------------------------------------------------------- */ +MODULE_SCOPE const TclStubs tclStubs; + +/* Dummy const structure returned by Tcl_InitSubsystems when + * using stubs, which looks like an Tcl_Interp, but in reality + * is not. It contains just enough for Tcl_InitStubs to be able + * to initialize the stub table. The first bytes of this structure + * are filled with the Tcl version string, so it can be cast to a + * "const char *" holding the Tcl version as well. */ +static const struct { + /* A real interpreter has interp->result/freeProc here: */ + const char version[sizeof(struct {char *r; void (*f)(void);})]; + int errorLine; + const struct TclStubs *stubTable; +} dummyInterp = { + TCL_PATCH_LEVEL, TCL_STUB_MAGIC, &tclStubs +}; + #undef Tcl_FindExecutable +const char * +Tcl_InitSubsystems(Tcl_PanicProc *panicProc) +{ + if (panicProc) { + Tcl_SetPanicProc(panicProc); + } + TclInitSubsystems(); + return dummyInterp.version; +} + void Tcl_FindExecutable( const char *argv0) /* The value of the application's argv[0] diff --git a/generic/tclMain.c b/generic/tclMain.c index f445383..38c4450 100644 --- a/generic/tclMain.c +++ b/generic/tclMain.c @@ -313,6 +313,8 @@ Tcl_MainEx( Tcl_Channel chan; InteractiveState is; + TclpSetInitialEncodings(); + TclpFindExecutable(argv[0]); Tcl_InitMemory(interp); is.interp = interp; diff --git a/generic/tclStubLib.c b/generic/tclStubLib.c index 859cbf9..3656f9a 100644 --- a/generic/tclStubLib.c +++ b/generic/tclStubLib.c @@ -73,37 +73,42 @@ Tcl_InitStubs( return NULL; } - actualVersion = stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 0, &pkgData); - if (actualVersion == NULL) { - return NULL; - } - if (exact) { - const char *p = version; - int count = 0; - - while (*p) { - count += !isDigit(*p++); + if(iPtr->errorLine == TCL_STUB_MAGIC) { + actualVersion = (const char *)interp; + tclStubsPtr = stubsPtr; + } else { + actualVersion = stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 0, &pkgData); + if (actualVersion == NULL) { + return NULL; } - if (count == 1) { - const char *q = actualVersion; + if (exact) { + const char *p = version; + int count = 0; - p = version; - while (*p && (*p == *q)) { - p++; q++; - } - if (*p || isDigit(*q)) { - /* Construct error message */ - stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL); - return NULL; + while (*p) { + count += !isDigit(*p++); } - } else { - actualVersion = stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL); - if (actualVersion == NULL) { - return NULL; + if (count == 1) { + const char *q = actualVersion; + + p = version; + while (*p && (*p == *q)) { + p++; q++; + } + if (*p || isDigit(*q)) { + /* Construct error message */ + stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL); + return NULL; + } + } else { + actualVersion = stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL); + if (actualVersion == NULL) { + return NULL; + } } } + tclStubsPtr = (const TclStubs *)pkgData; } - tclStubsPtr = (TclStubs *)pkgData; if (tclStubsPtr->hooks) { tclPlatStubsPtr = tclStubsPtr->hooks->tclPlatStubs; |