diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | doc/GetIndex.3 | 10 | ||||
-rw-r--r-- | generic/tclFileSystem.h | 43 | ||||
-rw-r--r-- | generic/tclIOUtil.c | 65 | ||||
-rw-r--r-- | generic/tclPathObj.c | 22 | ||||
-rwxr-xr-x | unix/configure | 2 | ||||
-rw-r--r-- | unix/tcl.m4 | 2 |
7 files changed, 85 insertions, 69 deletions
@@ -1,10 +1,18 @@ -2012-06-?? Harald Oehlmann <harald.oehlmann@elmicron.de> +2012-06-29 Harald Oehlmann <harald.oehlmann@elmicron.de> * library/msgcat/msgcat.tcl: [Bug 3536888] Locale guessing of msgcat * library/msgcat/pkgIndex.tcl: fails on (some) Windows 7. Bump to 1.4.5 * unix/Makefile.in * win/Makefile.in +2012-06-29 Donal K. Fellows <dkf@users.sf.net> + + * doc/GetIndex.3: Reinforced the description of the requirement for + the tables of names to index over to be static, following posting to + tcl-core by Brian Griffin about a bug caused by Tktreectrl not obeying + this rule correctly. This does not represent a functionality change, + merely a clearer documentation of a long-standing constraint. + 2012-06-25 Don Porter <dgp@users.sourceforge.net> * generic/tclFileSystem.h: [Bug 3024359] Make sure that the diff --git a/doc/GetIndex.3 b/doc/GetIndex.3 index 82590fb..45d4e9c 100644 --- a/doc/GetIndex.3 +++ b/doc/GetIndex.3 @@ -32,10 +32,16 @@ table entry. .AP "const char" **tablePtr in An array of null-terminated strings. The end of the array is marked by a NULL string pointer. +Note that references to the \fItablePtr\fR may be retained in the +internal representation of \fIobjPtr\fR, so this should represent the +address of a statically-allocated array. .AP "const void" *structTablePtr in An array of arbitrary type, typically some \fBstruct\fR type. The first member of the structure must be a null-terminated string. The size of the structure is given by \fIoffset\fR. +Note that references to the \fIstructTablePtr\fR may be retained in the +internal representation of \fIobjPtr\fR, so this should represent the +address of a statically-allocated array of structures. .AP int offset in The offset to add to structTablePtr to get to the next entry. The end of the array is marked by a NULL string pointer. @@ -52,10 +58,10 @@ The index of the string in \fItablePtr\fR that matches the value of .SH DESCRIPTION .PP -This procedure provides an efficient way for looking up keywords, +These procedures provide an efficient way for looking up keywords, switch names, option names, and similar things where the value of an object must be one of a predefined set of values. -\fIObjPtr\fR is compared against each of +\fBTcl_GetIndexFromObj\fR compares \fIobjPtr\fR against each of the strings in \fItablePtr\fR to find a match. A match occurs if \fIobjPtr\fR's string value is identical to one of the strings in \fItablePtr\fR, or if it is a non-empty unique abbreviation diff --git a/generic/tclFileSystem.h b/generic/tclFileSystem.h index 828e81d..02cb424 100644 --- a/generic/tclFileSystem.h +++ b/generic/tclFileSystem.h @@ -16,45 +16,6 @@ #include "tcl.h" /* - * struct FilesystemRecord -- - * - * A filesystem record is used to keep track of each filesystem currently - * registered with the core, in a linked list. Pointers to these structures - * are also kept by each "path" Tcl_Obj, and we must retain a refCount on the - * number of such references. - */ - -typedef struct FilesystemRecord { - ClientData clientData; /* Client specific data for the new filesystem - * (can be NULL) */ - Tcl_Filesystem *fsPtr; /* Pointer to filesystem dispatch table. */ - struct FilesystemRecord *nextPtr; - /* The next filesystem registered to Tcl, or - * NULL if no more. */ - struct FilesystemRecord *prevPtr; - /* The previous filesystem registered to Tcl, - * or NULL if no more. */ -} FilesystemRecord; - -/* - * This structure holds per-thread private copy of the current directory - * maintained by the global cwdPathPtr. This structure holds per-thread - * private copies of some global data. This way we avoid most of the - * synchronization calls which boosts performance, at cost of having to update - * this information each time the corresponding epoch counter changes. - */ - -typedef struct ThreadSpecificData { - int initialized; - int cwdPathEpoch; - int filesystemEpoch; - Tcl_Obj *cwdPathPtr; - ClientData cwdClientData; - FilesystemRecord *filesystemList; - int claims; -} ThreadSpecificData; - -/* * The internal TclFS API provides routines for handling and manipulating * paths efficiently, taking direct advantage of the "path" Tcl_Obj type. * @@ -62,8 +23,6 @@ typedef struct ThreadSpecificData { */ MODULE_SCOPE int TclFSCwdPointerEquals(Tcl_Obj **pathPtrPtr); -MODULE_SCOPE int TclFSMakePathFromNormalized(Tcl_Interp *interp, - Tcl_Obj *pathPtr); MODULE_SCOPE int TclFSNormalizeToUniquePath(Tcl_Interp *interp, Tcl_Obj *pathPtr, int startAt); MODULE_SCOPE Tcl_Obj * TclFSMakePathRelative(Tcl_Interp *interp, @@ -74,13 +33,13 @@ MODULE_SCOPE void TclFSSetPathDetails(Tcl_Obj *pathPtr, Tcl_Filesystem *fsPtr, ClientData clientData); MODULE_SCOPE Tcl_Obj * TclFSNormalizeAbsolutePath(Tcl_Interp *interp, Tcl_Obj *pathPtr); +MODULE_SCOPE int TclFSEpoch(void); /* * Private shared variables for use by tclIOUtil.c and tclPathObj.c */ MODULE_SCOPE Tcl_Filesystem tclNativeFilesystem; -MODULE_SCOPE Tcl_ThreadDataKey tclFsDataKey; /* * Private shared functions for use by tclIOUtil.c, tclPathObj.c and diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index b1b8961..6cf87ad 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -28,6 +28,43 @@ #include "tclFileSystem.h" /* + * struct FilesystemRecord -- + * + * A filesystem record is used to keep track of each filesystem currently + * registered with the core, in a linked list. + */ + +typedef struct FilesystemRecord { + ClientData clientData; /* Client specific data for the new filesystem + * (can be NULL) */ + Tcl_Filesystem *fsPtr; /* Pointer to filesystem dispatch table. */ + struct FilesystemRecord *nextPtr; + /* The next filesystem registered to Tcl, or + * NULL if no more. */ + struct FilesystemRecord *prevPtr; + /* The previous filesystem registered to Tcl, + * or NULL if no more. */ +} FilesystemRecord; + +/* + * This structure holds per-thread private copy of the current directory + * maintained by the global cwdPathPtr. This structure holds per-thread + * private copies of some global data. This way we avoid most of the + * synchronization calls which boosts performance, at cost of having to update + * this information each time the corresponding epoch counter changes. + */ + +typedef struct ThreadSpecificData { + int initialized; + int cwdPathEpoch; + int filesystemEpoch; + Tcl_Obj *cwdPathPtr; + ClientData cwdClientData; + FilesystemRecord *filesystemList; + int claims; +} ThreadSpecificData; + +/* * Prototypes for functions defined later in this file. */ @@ -430,7 +467,7 @@ static int cwdPathEpoch = 0; static ClientData cwdClientData = NULL; TCL_DECLARE_MUTEX(cwdMutex) -Tcl_ThreadDataKey tclFsDataKey; +static Tcl_ThreadDataKey fsDataKey; /* * One of these structures is used each time we successfully load a file from @@ -489,7 +526,7 @@ FsThrExitProc( int TclFSCwdIsNative(void) { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey); if (tsdPtr->cwdClientData != NULL) { return 1; @@ -523,7 +560,7 @@ int TclFSCwdPointerEquals( Tcl_Obj** pathPtrPtr) { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey); Tcl_MutexLock(&cwdMutex); if (tsdPtr->cwdPathPtr == NULL @@ -585,7 +622,7 @@ TclFSCwdPointerEquals( static void FsRecacheFilesystemList(void) { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey); FilesystemRecord *fsRecPtr, *tmpFsRecPtr = NULL, *toFree = NULL, *list; /* @@ -649,7 +686,7 @@ FsRecacheFilesystemList(void) static FilesystemRecord * FsGetFirstFilesystem(void) { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey); if (tsdPtr->filesystemList == NULL || ((tsdPtr->claims == 0) && (tsdPtr->filesystemEpoch != theFilesystemEpoch))) { FsRecacheFilesystemList(); @@ -672,16 +709,24 @@ TclFSEpochOk( static void Claim() { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey); tsdPtr->claims++; } static void Disclaim() { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey); tsdPtr->claims--; } + +int +TclFSEpoch() +{ + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey); + return tsdPtr->filesystemEpoch; +} + /* * If non-NULL, clientData is owned by us and must be freed later. @@ -694,7 +739,7 @@ FsUpdateCwd( { int len; char *str = NULL; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey); if (cwdObj != NULL) { str = Tcl_GetStringFromObj(cwdObj, &len); @@ -2624,7 +2669,7 @@ Tcl_Obj * Tcl_FSGetCwd( Tcl_Interp *interp) { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey); if (TclFSCwdPointerEquals(NULL)) { FilesystemRecord *fsRecPtr; @@ -2965,7 +3010,7 @@ Tcl_FSChdir( * instead. This should be examined by someone on Unix. */ - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey); ClientData cd; ClientData oldcd = tsdPtr->cwdClientData; diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c index 2e91922..ac9df3a 100644 --- a/generic/tclPathObj.c +++ b/generic/tclPathObj.c @@ -27,6 +27,8 @@ static int SetFsPathFromAny(Tcl_Interp *interp, Tcl_Obj *pathPtr); static int FindSplitPos(const char *path, int separator); static int IsSeparatorOrNull(int ch); static Tcl_Obj * GetExtension(Tcl_Obj *pathPtr); +static int MakePathFromNormalized(Tcl_Interp *interp, + Tcl_Obj *pathPtr); /* * Define the 'path' object type, which Tcl uses to represent file paths @@ -431,7 +433,7 @@ TclFSNormalizeAbsolutePath( * object into an FsPath for greater efficiency */ - TclFSMakePathFromNormalized(interp, retVal); + MakePathFromNormalized(interp, retVal); /* * This has a refCount of 1 for the caller, unlike many Tcl_Obj APIs. @@ -1525,7 +1527,7 @@ TclFSMakePathRelative( /* *--------------------------------------------------------------------------- * - * TclFSMakePathFromNormalized -- + * MakePathFromNormalized -- * * Like SetFsPathFromAny, but assumes the given object is an absolute * normalized path. Only for internal use. @@ -1539,13 +1541,12 @@ TclFSMakePathRelative( *--------------------------------------------------------------------------- */ -int -TclFSMakePathFromNormalized( +static int +MakePathFromNormalized( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ Tcl_Obj *pathPtr) /* The object to convert. */ { FsPath *fsPathPtr; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); if (pathPtr->typePtr == &tclFsPathType) { return TCL_OK; @@ -1587,7 +1588,7 @@ TclFSMakePathFromNormalized( fsPathPtr->nativePathPtr = NULL; fsPathPtr->fsPtr = NULL; /* Remember the epoch under which we decided pathPtr was normalized */ - fsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch; + fsPathPtr->filesystemEpoch = TclFSEpoch(); SETPATHOBJ(pathPtr, fsPathPtr); PATHFLAGS(pathPtr) = 0; @@ -1629,7 +1630,6 @@ Tcl_FSNewNativePath( Tcl_Obj *pathPtr = NULL; FsPath *fsPathPtr; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); if (fromFilesystem->internalToNormalizedProc != NULL) { pathPtr = (*fromFilesystem->internalToNormalizedProc)(clientData); @@ -1665,7 +1665,7 @@ Tcl_FSNewNativePath( fsPathPtr->cwdPtr = NULL; fsPathPtr->nativePathPtr = clientData; fsPathPtr->fsPtr = fromFilesystem; - fsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch; + fsPathPtr->filesystemEpoch = TclFSEpoch(); SETPATHOBJ(pathPtr, fsPathPtr); PATHFLAGS(pathPtr) = 0; @@ -2268,7 +2268,6 @@ TclFSSetPathDetails( Tcl_Filesystem *fsPtr, ClientData clientData) { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); FsPath *srcFsPathPtr; /* @@ -2284,7 +2283,7 @@ TclFSSetPathDetails( srcFsPathPtr = PATHOBJ(pathPtr); srcFsPathPtr->fsPtr = fsPtr; srcFsPathPtr->nativePathPtr = clientData; - srcFsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch; + srcFsPathPtr->filesystemEpoch = TclFSEpoch(); } /* @@ -2373,7 +2372,6 @@ SetFsPathFromAny( FsPath *fsPathPtr; Tcl_Obj *transPtr; char *name; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); if (pathPtr->typePtr == &tclFsPathType) { return TCL_OK; @@ -2530,7 +2528,7 @@ SetFsPathFromAny( if (transPtr != pathPtr) { Tcl_IncrRefCount(fsPathPtr->translatedPathPtr); /* Redo translation when $env(HOME) changes */ - fsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch; + fsPathPtr->filesystemEpoch = TclFSEpoch(); } else { fsPathPtr->filesystemEpoch = 0; } diff --git a/unix/configure b/unix/configure index f605d8a..0603bfc 100755 --- a/unix/configure +++ b/unix/configure @@ -7006,7 +7006,7 @@ echo "$as_me: error: ${CC} is not a cygwin compiler." >&2;} echo "$as_me: error: CYGWIN compile is only supported with --enable-threads" >&2;} { (exit 1); exit 1; }; } fi - if test ! -f "../win/tcldde13.dll" -a ! -f "../win/tk85.dll"; then + if test "x${SHARED_BUILD}" = "x1" -a ! -f "../win/tcldde13.dll" -a ! -f "../win/tk85.dll"; then { { echo "$as_me:$LINENO: error: Please configure and make the ../win directory first." >&5 echo "$as_me: error: Please configure and make the ../win directory first." >&2;} { (exit 1); exit 1; }; } diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 4de157c..3974753 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -1263,7 +1263,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ if test "x${TCL_THREADS}" = "x0"; then AC_MSG_ERROR([CYGWIN compile is only supported with --enable-threads]) fi - if test ! -f "../win/tcldde13.dll" -a ! -f "../win/tk85.dll"; then + if test "x${SHARED_BUILD}" = "x1" -a ! -f "../win/tcldde13.dll" -a ! -f "../win/tk85.dll"; then AC_MSG_ERROR([Please configure and make the ../win directory first.]) fi ;; |