summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2013-04-03 21:24:39 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2013-04-03 21:24:39 (GMT)
commit5821b2fb6d32fc0b83f7b88b10066a47de94a7df (patch)
treee479818aa2b7f9aa45d4d5954b6f1c8b4d37eff6
parent63dd224af5885144ab5a1de8919c5e8ea9d4b969 (diff)
parentf71425f1ea687ee9529bfd4fbff606ef58a09dc5 (diff)
downloadtcl-5821b2fb6d32fc0b83f7b88b10066a47de94a7df.zip
tcl-5821b2fb6d32fc0b83f7b88b10066a47de94a7df.tar.gz
tcl-5821b2fb6d32fc0b83f7b88b10066a47de94a7df.tar.bz2
rebase
-rw-r--r--doc/InitSubSyst.353
-rw-r--r--generic/tcl.h12
-rw-r--r--generic/tclEncoding.c36
-rw-r--r--generic/tclMain.c2
-rw-r--r--generic/tclStubLib.c55
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;