summaryrefslogtreecommitdiffstats
path: root/generic/tclUtil.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclUtil.c')
-rw-r--r--generic/tclUtil.c163
1 files changed, 72 insertions, 91 deletions
diff --git a/generic/tclUtil.c b/generic/tclUtil.c
index 9737c4a..7bf4b41 100644
--- a/generic/tclUtil.c
+++ b/generic/tclUtil.c
@@ -11,37 +11,16 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclUtil.c,v 1.49 2004/11/30 19:34:50 dgp Exp $
+ * RCS: @(#) $Id: tclUtil.c,v 1.50 2004/12/01 23:18:54 dgp Exp $
*/
#include "tclInt.h"
/*
- * The following variables hold the full path name of the binary
- * from which this application was executed, or NULL if it isn't
- * know. The values are set by the procedure Tcl_FindExecutable.
- * Only the first call to Tcl_FindExecutable sets the value. That
- * call also sets the "searchDone" flag, so that subsequent calls
- * are no-ops. With that logic in place, no mutex protection is
- * required. The storage space is dynamically allocated. The value
- * is kept in the system encoding.
+ * The absolute pathname of the executable in which this Tcl library
+ * is running.
*/
-
-char *tclNativeExecutableName = NULL;
-int tclFindExecutableSearchDone = 0;
-
-/*
- * A copy of the executable path name, converted to Tcl's internal
- * encoding, UTF-8. Also keep a copy of what the system encoding
- * was believed to be when the conversion was done, just in case
- * it's changed on us. Because Tcl_GetNameOfExecutable() is in
- * the public API, it might be called from any thread, so we need
- * mutex protection here.
- */
-
-TCL_DECLARE_MUTEX(executableNameMutex)
-static char *executableName = NULL;
-static Tcl_Encoding conversionEncoding = NULL;
+static ProcessGlobalValue executableName = {0, 0, NULL, NULL, NULL, NULL, NULL};
/*
* The following values are used in the flags returned by Tcl_ScanElement
@@ -90,7 +69,6 @@ TCL_DECLARE_MUTEX(precisionMutex)
*/
static void ClearHash _ANSI_ARGS_((Tcl_HashTable *tablePtr));
-static void FreeExecutableName _ANSI_ARGS_((ClientData));
static void FreeProcessGlobalValue _ANSI_ARGS_((
ClientData clientData));
static void FreeThreadHash _ANSI_ARGS_ ((ClientData clientData));
@@ -98,7 +76,6 @@ static Tcl_HashTable * GetThreadHash _ANSI_ARGS_ ((Tcl_ThreadDataKey *keyPtr));
static int SetEndOffsetFromAny _ANSI_ARGS_((Tcl_Interp* interp,
Tcl_Obj* objPtr));
static void UpdateStringOfEndOffset _ANSI_ARGS_((Tcl_Obj* objPtr));
-static Tcl_Obj * Tcl_GetObjNameOfExecutable();
/*
* The following is the Tcl object type definition for an object
@@ -2700,9 +2677,10 @@ FreeProcessGlobalValue(clientData)
*----------------------------------------------------------------------
*/
void
-TclSetProcessGlobalValue(pgvPtr, newValue)
+TclSetProcessGlobalValue(pgvPtr, newValue, encoding)
ProcessGlobalValue *pgvPtr;
Tcl_Obj *newValue;
+ Tcl_Encoding encoding;
{
CONST char *bytes;
Tcl_HashTable *cacheMap;
@@ -2722,8 +2700,8 @@ TclSetProcessGlobalValue(pgvPtr, newValue)
strcpy(pgvPtr->value, bytes);
if (pgvPtr->encoding) {
Tcl_FreeEncoding(pgvPtr->encoding);
- pgvPtr->encoding = NULL;
}
+ pgvPtr->encoding = encoding;
/*
* Fill the local thread copy directly with the Tcl_Obj
@@ -2820,88 +2798,91 @@ TclGetProcessGlobalValue(pgvPtr)
/*
*----------------------------------------------------------------------
*
- * Tcl_GetNameOfExecutable --
- *
- * This procedure simply returns a pointer to the internal full
- * path name of the executable file as computed by
- * Tcl_FindExecutable. This procedure call is the C API
- * equivalent to the "info nameofexecutable" command.
+ * TclSetObjNameOfExecutable --
*
- * TODO: Rework these routines to use a ProcessGlobalValue.
+ * This procedure stores the absolute pathname of
+ * the executable file (normally as computed by
+ * TclpFindExecutable).
*
* Results:
- * A pointer to the internal string or NULL if the internal full
- * path name has not been computed or unknown.
+ * None.
*
* Side effects:
- * The object referenced by "objPtr" might be converted to an
- * integer object.
+ * Stores the executable name.
*
*----------------------------------------------------------------------
*/
-static void
-FreeExecutableName(clientData)
- ClientData clientData;
+void
+TclSetObjNameOfExecutable(name, encoding)
+ Tcl_Obj *name;
+ Tcl_Encoding encoding;
{
- Tcl_FreeEncoding(conversionEncoding);
- conversionEncoding = NULL;
- if (NULL != executableName) {
- ckfree(executableName);
- }
- executableName = NULL;
+ TclSetProcessGlobalValue(&executableName, name, encoding);
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetObjNameOfExecutable --
+ *
+ * This procedure retrieves the absolute pathname of the
+ * application in which the Tcl library is running, usually
+ * as previously stored by TclpFindExecutable().
+ * This procedure call is the C API equivalent to the
+ * "info nameofexecutable" command.
+ *
+ * Results:
+ * A pointer to an "fsPath" Tcl_Obj, or to an empty Tcl_Obj if
+ * the pathname of the application is unknown.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
-static Tcl_Obj *
-Tcl_GetObjNameOfExecutable()
+Tcl_Obj *
+TclGetObjNameOfExecutable()
{
- Tcl_Obj *result;
-
- Tcl_MutexLock(&executableNameMutex);
- if (NULL == conversionEncoding) {
- /* First call (after free) */
- conversionEncoding = Tcl_GetEncoding(NULL, NULL);
- Tcl_CreateExitHandler(FreeExecutableName, NULL);
- } else {
- /* Later call... */
- Tcl_Encoding systemEncoding = Tcl_GetEncoding(NULL, NULL);
- if (systemEncoding != conversionEncoding) {
- /* ...with system encoding changed */
- FreeExecutableName(NULL);
- conversionEncoding = systemEncoding;
- } else {
- Tcl_FreeEncoding(systemEncoding);
- }
- }
- if (NULL == tclNativeExecutableName) {
- FreeExecutableName(NULL);
- } else if (NULL == executableName) {
- Tcl_DString ds;
- Tcl_ExternalToUtfDString(conversionEncoding,
- tclNativeExecutableName, -1, &ds);
- executableName = (char *)
- ckalloc ((unsigned) Tcl_DStringLength(&ds) + 1);
- strcpy(executableName, Tcl_DStringValue(&ds));
- Tcl_DStringFree(&ds);
- }
-
- if (NULL == executableName) {
- result = Tcl_NewObj();
- } else {
- result = Tcl_NewStringObj(executableName, -1);
- }
- Tcl_MutexUnlock(&executableNameMutex);
- return result;
+ return TclGetProcessGlobalValue(&executableName);
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetNameOfExecutable --
+ *
+ * This procedure retrieves the absolute pathname of the
+ * application in which the Tcl library is running, and
+ * returns it in string form.
+ *
+ * The returned string belongs to Tcl and should be copied
+ * if the caller plans to keep it, to guard against it
+ * becoming invalid.
+ *
+ * Results:
+ * A pointer to the internal string or NULL if the internal full
+ * path name has not been computed or unknown.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
CONST char *
Tcl_GetNameOfExecutable()
{
- Tcl_DecrRefCount(Tcl_GetObjNameOfExecutable());
- return executableName;
+ int numBytes;
+ CONST char * bytes =
+ Tcl_GetStringFromObj(TclGetObjNameOfExecutable(), &numBytes);
+ if (numBytes == 0) {
+ return NULL;
+ }
+ return bytes;
}
-
/*
*----------------------------------------------------------------------
*