summaryrefslogtreecommitdiffstats
path: root/generic/tclEncoding.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclEncoding.c')
-rw-r--r--generic/tclEncoding.c952
1 files changed, 630 insertions, 322 deletions
diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c
index 2d942c9..d246cb2 100644
--- a/generic/tclEncoding.c
+++ b/generic/tclEncoding.c
@@ -7,13 +7,11 @@
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
- *
- * RCS: @(#) $Id: tclEncoding.c,v 1.38 2005/10/18 15:01:56 dkf Exp $
*/
#include "tclInt.h"
-typedef size_t (LengthProc)(CONST char *src);
+typedef size_t (LengthProc)(const char *src);
/*
* The following data structure represents an encoding, which describes how to
@@ -94,7 +92,7 @@ typedef struct TableEncodingData {
*/
typedef struct EscapeSubTable {
- unsigned int sequenceLen; /* Length of following string. */
+ unsigned sequenceLen; /* Length of following string. */
char sequence[16]; /* Escape code that marks this encoding. */
char name[32]; /* Name for encoding. */
Encoding *encodingPtr; /* Encoding loaded using above name, or NULL
@@ -106,10 +104,10 @@ typedef struct EscapeEncodingData {
int fallback; /* Character (in this encoding) to substitute
* when this encoding cannot represent a UTF-8
* character. */
- unsigned int initLen; /* Length of following string. */
+ unsigned initLen; /* Length of following string. */
char init[16]; /* String to emit or expect before first char
* in conversion. */
- unsigned int finalLen; /* Length of following string. */
+ unsigned finalLen; /* Length of following string. */
char final[16]; /* String to emit or expect after last char in
* conversion. */
char prefixBytes[256]; /* If a byte in the input stream is the first
@@ -184,6 +182,7 @@ TCL_DECLARE_MUTEX(encodingMutex)
static Tcl_Encoding defaultEncoding;
static Tcl_Encoding systemEncoding;
+Tcl_Encoding tclIdentityEncoding;
/*
* The following variable is used in the sparse matrix code for a
@@ -197,19 +196,19 @@ static unsigned short emptyPage[256];
*/
static int BinaryProc(ClientData clientData,
- CONST char *src, int srcLen, int flags,
+ const char *src, int srcLen, int flags,
Tcl_EncodingState *statePtr, char *dst, int dstLen,
int *srcReadPtr, int *dstWrotePtr,
int *dstCharsPtr);
static void DupEncodingIntRep(Tcl_Obj *srcPtr, Tcl_Obj *dupPtr);
static void EscapeFreeProc(ClientData clientData);
static int EscapeFromUtfProc(ClientData clientData,
- CONST char *src, int srcLen, int flags,
+ const char *src, int srcLen, int flags,
Tcl_EncodingState *statePtr, char *dst, int dstLen,
int *srcReadPtr, int *dstWrotePtr,
int *dstCharsPtr);
static int EscapeToUtfProc(ClientData clientData,
- CONST char *src, int srcLen, int flags,
+ const char *src, int srcLen, int flags,
Tcl_EncodingState *statePtr, char *dst, int dstLen,
int *srcReadPtr, int *dstWrotePtr,
int *dstCharsPtr);
@@ -218,63 +217,73 @@ static void FreeEncoding(Tcl_Encoding encoding);
static void FreeEncodingIntRep(Tcl_Obj *objPtr);
static Encoding * GetTableEncoding(EscapeEncodingData *dataPtr,
int state);
-static Tcl_Encoding LoadEncodingFile(Tcl_Interp *interp, CONST char *name);
-static Tcl_Encoding LoadTableEncoding(CONST char *name, int type,
+static Tcl_Encoding LoadEncodingFile(Tcl_Interp *interp, const char *name);
+static Tcl_Encoding LoadTableEncoding(const char *name, int type,
Tcl_Channel chan);
-static Tcl_Encoding LoadEscapeEncoding(CONST char *name, Tcl_Channel chan);
+static Tcl_Encoding LoadEscapeEncoding(const char *name, Tcl_Channel chan);
static Tcl_Channel OpenEncodingFileChannel(Tcl_Interp *interp,
- CONST char *name);
+ const char *name);
static void TableFreeProc(ClientData clientData);
static int TableFromUtfProc(ClientData clientData,
- CONST char *src, int srcLen, int flags,
+ const char *src, int srcLen, int flags,
Tcl_EncodingState *statePtr, char *dst, int dstLen,
int *srcReadPtr, int *dstWrotePtr,
int *dstCharsPtr);
-static int TableToUtfProc(ClientData clientData, CONST char *src,
+static int TableToUtfProc(ClientData clientData, const char *src,
int srcLen, int flags, Tcl_EncodingState *statePtr,
char *dst, int dstLen, int *srcReadPtr,
int *dstWrotePtr, int *dstCharsPtr);
-static size_t unilen(CONST char *src);
+static size_t unilen(const char *src);
static int UnicodeToUtfProc(ClientData clientData,
- CONST char *src, int srcLen, int flags,
+ const char *src, int srcLen, int flags,
Tcl_EncodingState *statePtr, char *dst, int dstLen,
int *srcReadPtr, int *dstWrotePtr,
int *dstCharsPtr);
static int UtfToUnicodeProc(ClientData clientData,
- CONST char *src, int srcLen, int flags,
+ const char *src, int srcLen, int flags,
Tcl_EncodingState *statePtr, char *dst, int dstLen,
int *srcReadPtr, int *dstWrotePtr,
int *dstCharsPtr);
static int UtfToUtfProc(ClientData clientData,
- CONST char *src, int srcLen, int flags,
+ const char *src, int srcLen, int flags,
Tcl_EncodingState *statePtr, char *dst, int dstLen,
int *srcReadPtr, int *dstWrotePtr,
int *dstCharsPtr, int pureNullMode);
static int UtfIntToUtfExtProc(ClientData clientData,
- CONST char *src, int srcLen, int flags,
+ const char *src, int srcLen, int flags,
Tcl_EncodingState *statePtr, char *dst, int dstLen,
int *srcReadPtr, int *dstWrotePtr,
int *dstCharsPtr);
static int UtfExtToUtfIntProc(ClientData clientData,
- CONST char *src, int srcLen, int flags,
+ const char *src, int srcLen, int flags,
Tcl_EncodingState *statePtr, char *dst, int dstLen,
int *srcReadPtr, int *dstWrotePtr,
int *dstCharsPtr);
+static int Iso88591FromUtfProc(ClientData clientData,
+ const char *src, int srcLen, int flags,
+ Tcl_EncodingState *statePtr, char *dst, int dstLen,
+ int *srcReadPtr, int *dstWrotePtr,
+ int *dstCharsPtr);
+static int Iso88591ToUtfProc(ClientData clientData,
+ const char *src, int srcLen, int flags,
+ Tcl_EncodingState *statePtr, char *dst,
+ int dstLen, int *srcReadPtr, int *dstWrotePtr,
+ int *dstCharsPtr);
/*
- * A Tcl_ObjType for holding a cached Tcl_Encoding as the intrep. This should
- * help the lifetime of encodings be more useful. See concerns raised in [Bug
- * 1077262].
+ * A Tcl_ObjType for holding a cached Tcl_Encoding in the twoPtrValue.ptr1 field
+ * of the intrep. This should help the lifetime of encodings be more useful.
+ * See concerns raised in [Bug 1077262].
*/
-static Tcl_ObjType EncodingType = {
+static const Tcl_ObjType encodingType = {
"encoding", FreeEncodingIntRep, DupEncodingIntRep, NULL, NULL
};
/*
*----------------------------------------------------------------------
*
- * TclGetEncodingFromObj --
+ * Tcl_GetEncodingFromObj --
*
* Writes to (*encodingPtr) the Tcl_Encoding value of (*objPtr), if
* possible, and returns TCL_OK. If no such encoding exists, TCL_ERROR is
@@ -285,27 +294,28 @@ static Tcl_ObjType EncodingType = {
* Standard Tcl return code.
*
* Side effects:
- * Caches the Tcl_Encoding value as the internal rep of (*objPtr).
+ * Caches the Tcl_Encoding value as the internal rep of (*objPtr).
*
*----------------------------------------------------------------------
*/
int
-TclGetEncodingFromObj(
+Tcl_GetEncodingFromObj(
Tcl_Interp *interp,
Tcl_Obj *objPtr,
Tcl_Encoding *encodingPtr)
{
- CONST char *name = Tcl_GetString(objPtr);
- if (objPtr->typePtr != &EncodingType) {
+ const char *name = Tcl_GetString(objPtr);
+
+ if (objPtr->typePtr != &encodingType) {
Tcl_Encoding encoding = Tcl_GetEncoding(interp, name);
if (encoding == NULL) {
return TCL_ERROR;
}
TclFreeIntRep(objPtr);
- objPtr->internalRep.otherValuePtr = (VOID *) encoding;
- objPtr->typePtr = &EncodingType;
+ objPtr->internalRep.twoPtrValue.ptr1 = encoding;
+ objPtr->typePtr = &encodingType;
}
*encodingPtr = Tcl_GetEncoding(NULL, name);
return TCL_OK;
@@ -325,7 +335,8 @@ static void
FreeEncodingIntRep(
Tcl_Obj *objPtr)
{
- Tcl_FreeEncoding((Tcl_Encoding) objPtr->internalRep.otherValuePtr);
+ Tcl_FreeEncoding(objPtr->internalRep.twoPtrValue.ptr1);
+ objPtr->typePtr = NULL;
}
/*
@@ -343,14 +354,13 @@ DupEncodingIntRep(
Tcl_Obj *srcPtr,
Tcl_Obj *dupPtr)
{
- dupPtr->internalRep.otherValuePtr = (VOID *)
- Tcl_GetEncoding(NULL, srcPtr->bytes);
+ dupPtr->internalRep.twoPtrValue.ptr1 = Tcl_GetEncoding(NULL, srcPtr->bytes);
}
/*
*----------------------------------------------------------------------
*
- * TclGetEncodingSearchPath --
+ * Tcl_GetEncodingSearchPath --
*
* Keeps the per-thread copy of the encoding search path current with
* changes to the global copy.
@@ -362,7 +372,7 @@ DupEncodingIntRep(
*/
Tcl_Obj *
-TclGetEncodingSearchPath(void)
+Tcl_GetEncodingSearchPath(void)
{
return TclGetProcessGlobalValue(&encodingSearchPath);
}
@@ -370,7 +380,7 @@ TclGetEncodingSearchPath(void)
/*
*----------------------------------------------------------------------
*
- * TclSetEncodingSearchPath --
+ * Tcl_SetEncodingSearchPath --
*
* Keeps the per-thread copy of the encoding search path current with
* changes to the global copy.
@@ -379,7 +389,7 @@ TclGetEncodingSearchPath(void)
*/
int
-TclSetEncodingSearchPath(
+Tcl_SetEncodingSearchPath(
Tcl_Obj *searchPath)
{
int dummy;
@@ -443,8 +453,8 @@ TclSetLibraryPath(
*
* FillEncodingFileMap --
*
- * Called to bring the encoding file map in sync with the current value
- * of the encoding search path.
+ * Called to bring the encoding file map in sync with the current value
+ * of the encoding search path.
*
* Scan the directories on the encoding search path, find the *.enc
* files, and store the found pathnames in a map associated with the
@@ -470,7 +480,7 @@ FillEncodingFileMap(void)
int i, numDirs = 0;
Tcl_Obj *map, *searchPath;
- searchPath = TclGetEncodingSearchPath();
+ searchPath = Tcl_GetEncodingSearchPath();
Tcl_IncrRefCount(searchPath);
Tcl_ListObjLength(NULL, searchPath, &numDirs);
map = Tcl_NewDictObj();
@@ -497,12 +507,12 @@ FillEncodingFileMap(void)
Tcl_ListObjGetElements(NULL, matchFileList, &numFiles, &filev);
for (j=0; j<numFiles; j++) {
- Tcl_Obj *encodingName, *file;
+ Tcl_Obj *encodingName, *fileObj;
- file = TclPathPart(NULL, filev[j], TCL_PATH_TAIL);
- encodingName = TclPathPart(NULL, file, TCL_PATH_ROOT);
+ fileObj = TclPathPart(NULL, filev[j], TCL_PATH_TAIL);
+ encodingName = TclPathPart(NULL, fileObj, TCL_PATH_ROOT);
Tcl_DictObjPut(NULL, map, encodingName, directory);
- Tcl_DecrRefCount(file);
+ Tcl_DecrRefCount(fileObj);
Tcl_DecrRefCount(encodingName);
}
Tcl_DecrRefCount(matchFileList);
@@ -534,6 +544,9 @@ void
TclInitEncodingSubsystem(void)
{
Tcl_EncodingType type;
+ TableEncodingData *dataPtr;
+ unsigned size;
+ unsigned short i;
if (encodingsInitialized) {
return;
@@ -555,9 +568,7 @@ TclInitEncodingSubsystem(void)
type.freeProc = NULL;
type.nullSize = 1;
type.clientData = NULL;
-
- defaultEncoding = Tcl_CreateEncoding(&type);
- systemEncoding = Tcl_GetEncoding(NULL, type.encodingName);
+ tclIdentityEncoding = Tcl_CreateEncoding(&type);
type.encodingName = "utf-8";
type.toUtfProc = UtfExtToUtfIntProc;
@@ -575,6 +586,44 @@ TclInitEncodingSubsystem(void)
type.clientData = NULL;
Tcl_CreateEncoding(&type);
+ /*
+ * Need the iso8859-1 encoding in order to process binary data, so force
+ * it to always be embedded. Note that this encoding *must* be a proper
+ * table encoding or some of the escape encodings crash! Hence the ugly
+ * code to duplicate the structure of a table encoding here.
+ */
+
+ dataPtr = ckalloc(sizeof(TableEncodingData));
+ memset(dataPtr, 0, sizeof(TableEncodingData));
+ dataPtr->fallback = '?';
+
+ size = 256*(sizeof(unsigned short *) + sizeof(unsigned short));
+ dataPtr->toUnicode = ckalloc(size);
+ memset(dataPtr->toUnicode, 0, size);
+ dataPtr->fromUnicode = ckalloc(size);
+ memset(dataPtr->fromUnicode, 0, size);
+
+ dataPtr->toUnicode[0] = (unsigned short *) (dataPtr->toUnicode + 256);
+ dataPtr->fromUnicode[0] = (unsigned short *) (dataPtr->fromUnicode + 256);
+ for (i=1 ; i<256 ; i++) {
+ dataPtr->toUnicode[i] = emptyPage;
+ dataPtr->fromUnicode[i] = emptyPage;
+ }
+
+ for (i=0 ; i<256 ; i++) {
+ dataPtr->toUnicode[0][i] = i;
+ dataPtr->fromUnicode[0][i] = i;
+ }
+
+ type.encodingName = "iso8859-1";
+ type.toUtfProc = Iso88591ToUtfProc;
+ type.fromUtfProc = Iso88591FromUtfProc;
+ type.freeProc = TableFreeProc;
+ type.nullSize = 1;
+ type.clientData = dataPtr;
+ defaultEncoding = Tcl_CreateEncoding(&type);
+ systemEncoding = Tcl_GetEncoding(NULL, type.encodingName);
+
encodingsInitialized = 1;
}
@@ -603,6 +652,7 @@ TclFinalizeEncodingSubsystem(void)
Tcl_MutexLock(&encodingMutex);
encodingsInitialized = 0;
FreeEncoding(systemEncoding);
+ FreeEncoding(tclIdentityEncoding);
hPtr = Tcl_FirstHashEntry(&encodingTable, &search);
while (hPtr != NULL) {
@@ -613,7 +663,7 @@ TclFinalizeEncodingSubsystem(void)
* cleaned up.
*/
- FreeEncoding((Tcl_Encoding) Tcl_GetHashValue(hPtr));
+ FreeEncoding(Tcl_GetHashValue(hPtr));
hPtr = Tcl_FirstHashEntry(&encodingTable, &search);
}
@@ -626,24 +676,24 @@ TclFinalizeEncodingSubsystem(void)
*
* Tcl_GetDefaultEncodingDir --
*
- * Legacy public interface to retrieve first directory in the encoding
- * searchPath.
+ * Legacy public interface to retrieve first directory in the encoding
+ * searchPath.
*
* Results:
* The directory pathname, as a string, or NULL for an empty encoding
* search path.
*
* Side effects:
- * None.
+ * None.
*
*-------------------------------------------------------------------------
*/
-CONST char *
+const char *
Tcl_GetDefaultEncodingDir(void)
{
int numDirs;
- Tcl_Obj *first, *searchPath = TclGetEncodingSearchPath();
+ Tcl_Obj *first, *searchPath = Tcl_GetEncodingSearchPath();
Tcl_ListObjLength(NULL, searchPath, &numDirs);
if (numDirs == 0) {
@@ -659,28 +709,28 @@ Tcl_GetDefaultEncodingDir(void)
*
* Tcl_SetDefaultEncodingDir --
*
- * Legacy public interface to set the first directory in the encoding
- * search path.
+ * Legacy public interface to set the first directory in the encoding
+ * search path.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Modifies the encoding search path.
+ * Modifies the encoding search path.
*
*-------------------------------------------------------------------------
*/
void
Tcl_SetDefaultEncodingDir(
- CONST char *path)
+ const char *path)
{
- Tcl_Obj *searchPath = TclGetEncodingSearchPath();
+ Tcl_Obj *searchPath = Tcl_GetEncodingSearchPath();
Tcl_Obj *directory = Tcl_NewStringObj(path, -1);
searchPath = Tcl_DuplicateObj(searchPath);
Tcl_ListObjReplace(NULL, searchPath, 0, 0, 1, &directory);
- TclSetEncodingSearchPath(searchPath);
+ Tcl_SetEncodingSearchPath(searchPath);
}
/*
@@ -711,7 +761,7 @@ Tcl_SetDefaultEncodingDir(
Tcl_Encoding
Tcl_GetEncoding(
Tcl_Interp *interp, /* Interp for error reporting, if not NULL. */
- CONST char *name) /* The name of the desired encoding. */
+ const char *name) /* The name of the desired encoding. */
{
Tcl_HashEntry *hPtr;
Encoding *encodingPtr;
@@ -726,7 +776,7 @@ Tcl_GetEncoding(
hPtr = Tcl_FindHashEntry(&encodingTable, name);
if (hPtr != NULL) {
- encodingPtr = (Encoding *) Tcl_GetHashValue(hPtr);
+ encodingPtr = Tcl_GetHashValue(hPtr);
encodingPtr->refCount++;
Tcl_MutexUnlock(&encodingMutex);
return (Tcl_Encoding) encodingPtr;
@@ -785,22 +835,24 @@ static void
FreeEncoding(
Tcl_Encoding encoding)
{
- Encoding *encodingPtr;
+ Encoding *encodingPtr = (Encoding *) encoding;
- encodingPtr = (Encoding *) encoding;
if (encodingPtr == NULL) {
return;
}
+ if (encodingPtr->refCount<=0) {
+ Tcl_Panic("FreeEncoding: refcount problem !!!");
+ }
encodingPtr->refCount--;
if (encodingPtr->refCount == 0) {
if (encodingPtr->freeProc != NULL) {
- (*encodingPtr->freeProc)(encodingPtr->clientData);
+ encodingPtr->freeProc(encodingPtr->clientData);
}
if (encodingPtr->hPtr != NULL) {
Tcl_DeleteHashEntry(encodingPtr->hPtr);
}
- ckfree((char *) encodingPtr->name);
- ckfree((char *) encodingPtr);
+ ckfree(encodingPtr->name);
+ ckfree(encodingPtr);
}
}
@@ -821,7 +873,7 @@ FreeEncoding(
*---------------------------------------------------------------------------
*/
-CONST char *
+const char *
Tcl_GetEncodingName(
Tcl_Encoding encoding) /* The encoding whose name to fetch. */
{
@@ -870,9 +922,10 @@ Tcl_GetEncodingNames(
Tcl_MutexLock(&encodingMutex);
for (hPtr = Tcl_FirstHashEntry(&encodingTable, &search); hPtr != NULL;
hPtr = Tcl_NextHashEntry(&search)) {
- Encoding *encodingPtr = (Encoding *) Tcl_GetHashValue(hPtr);
+ Encoding *encodingPtr = Tcl_GetHashValue(hPtr);
+
Tcl_CreateHashEntry(&table,
- (char *) Tcl_NewStringObj(encodingPtr->name, -1), &dummy);
+ Tcl_NewStringObj(encodingPtr->name, -1), &dummy);
}
Tcl_MutexUnlock(&encodingMutex);
@@ -885,7 +938,7 @@ Tcl_GetEncodingNames(
Tcl_DictObjFirst(NULL, map, &mapSearch, &name, NULL, &done);
for (; !done; Tcl_DictObjNext(&mapSearch, &name, NULL, &done)) {
- Tcl_CreateHashEntry(&table, (char *) name, &dummy);
+ Tcl_CreateHashEntry(&table, name, &dummy);
}
/*
@@ -928,13 +981,13 @@ Tcl_GetEncodingNames(
int
Tcl_SetSystemEncoding(
Tcl_Interp *interp, /* Interp for error reporting, if not NULL. */
- CONST char *name) /* The name of the desired encoding, or NULL
+ const char *name) /* The name of the desired encoding, or NULL/""
* to reset to default encoding. */
{
Tcl_Encoding encoding;
Encoding *encodingPtr;
- if (name == NULL) {
+ if (!name || !*name) {
Tcl_MutexLock(&encodingMutex);
encoding = defaultEncoding;
encodingPtr = (Encoding *) encoding;
@@ -983,28 +1036,29 @@ Tcl_SetSystemEncoding(
Tcl_Encoding
Tcl_CreateEncoding(
- Tcl_EncodingType *typePtr) /* The encoding type. */
+ const Tcl_EncodingType *typePtr)
+ /* The encoding type. */
{
Tcl_HashEntry *hPtr;
- int new;
+ int isNew;
Encoding *encodingPtr;
char *name;
Tcl_MutexLock(&encodingMutex);
- hPtr = Tcl_CreateHashEntry(&encodingTable, typePtr->encodingName, &new);
- if (new == 0) {
+ hPtr = Tcl_CreateHashEntry(&encodingTable, typePtr->encodingName, &isNew);
+ if (isNew == 0) {
/*
* Remove old encoding from hash table, but don't delete it until last
* reference goes away.
*/
- encodingPtr = (Encoding *) Tcl_GetHashValue(hPtr);
+ encodingPtr = Tcl_GetHashValue(hPtr);
encodingPtr->hPtr = NULL;
}
- name = ckalloc((unsigned) strlen(typePtr->encodingName) + 1);
+ name = ckalloc(strlen(typePtr->encodingName) + 1);
- encodingPtr = (Encoding *) ckalloc(sizeof(Encoding));
+ encodingPtr = ckalloc(sizeof(Encoding));
encodingPtr->name = strcpy(name, typePtr->encodingName);
encodingPtr->toUtfProc = typePtr->toUtfProc;
encodingPtr->fromUtfProc = typePtr->fromUtfProc;
@@ -1050,7 +1104,7 @@ char *
Tcl_ExternalToUtfDString(
Tcl_Encoding encoding, /* The encoding for the source string, or NULL
* for the default system encoding. */
- CONST char *src, /* Source string in specified encoding. */
+ const char *src, /* Source string in specified encoding. */
int srcLen, /* Source string length in bytes, or < 0 for
* encoding-specific string length. */
Tcl_DString *dstPtr) /* Uninitialized or free DString in which the
@@ -1058,7 +1112,7 @@ Tcl_ExternalToUtfDString(
{
char *dst;
Tcl_EncodingState state;
- Encoding *encodingPtr;
+ const Encoding *encodingPtr;
int flags, dstLen, result, soFar, srcRead, dstWrote, dstChars;
Tcl_DStringInit(dstPtr);
@@ -1073,15 +1127,14 @@ Tcl_ExternalToUtfDString(
if (src == NULL) {
srcLen = 0;
} else if (srcLen < 0) {
- srcLen = (*encodingPtr->lengthProc)(src);
+ srcLen = encodingPtr->lengthProc(src);
}
flags = TCL_ENCODING_START | TCL_ENCODING_END;
while (1) {
- result = (*encodingPtr->toUtfProc)(encodingPtr->clientData, src,
- srcLen, flags, &state, dst, dstLen, &srcRead, &dstWrote,
- &dstChars);
+ result = encodingPtr->toUtfProc(encodingPtr->clientData, src, srcLen,
+ flags, &state, dst, dstLen, &srcRead, &dstWrote, &dstChars);
soFar = dst + dstWrote - Tcl_DStringValue(dstPtr);
if (result != TCL_CONVERT_NOSPACE) {
@@ -1124,7 +1177,7 @@ Tcl_ExternalToUtf(
Tcl_Interp *interp, /* Interp for error return, if not NULL. */
Tcl_Encoding encoding, /* The encoding for the source string, or NULL
* for the default system encoding. */
- CONST char *src, /* Source string in specified encoding. */
+ const char *src, /* Source string in specified encoding. */
int srcLen, /* Source string length in bytes, or < 0 for
* encoding-specific string length. */
int flags, /* Conversion control flags. */
@@ -1149,7 +1202,7 @@ Tcl_ExternalToUtf(
* correspond to the bytes stored in the
* output buffer. */
{
- Encoding *encodingPtr;
+ const Encoding *encodingPtr;
int result, srcRead, dstWrote, dstChars;
Tcl_EncodingState state;
@@ -1161,7 +1214,7 @@ Tcl_ExternalToUtf(
if (src == NULL) {
srcLen = 0;
} else if (srcLen < 0) {
- srcLen = (*encodingPtr->lengthProc)(src);
+ srcLen = encodingPtr->lengthProc(src);
}
if (statePtr == NULL) {
flags |= TCL_ENCODING_START | TCL_ENCODING_END;
@@ -1184,7 +1237,7 @@ Tcl_ExternalToUtf(
*/
dstLen--;
- result = (*encodingPtr->toUtfProc)(encodingPtr->clientData, src, srcLen,
+ result = encodingPtr->toUtfProc(encodingPtr->clientData, src, srcLen,
flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr,
dstCharsPtr);
dst[*dstWrotePtr] = '\0';
@@ -1217,7 +1270,7 @@ char *
Tcl_UtfToExternalDString(
Tcl_Encoding encoding, /* The encoding for the converted string, or
* NULL for the default system encoding. */
- CONST char *src, /* Source string in UTF-8. */
+ const char *src, /* Source string in UTF-8. */
int srcLen, /* Source string length in bytes, or < 0 for
* strlen(). */
Tcl_DString *dstPtr) /* Uninitialized or free DString in which the
@@ -1225,7 +1278,7 @@ Tcl_UtfToExternalDString(
{
char *dst;
Tcl_EncodingState state;
- Encoding *encodingPtr;
+ const Encoding *encodingPtr;
int flags, dstLen, result, soFar, srcRead, dstWrote, dstChars;
Tcl_DStringInit(dstPtr);
@@ -1244,7 +1297,7 @@ Tcl_UtfToExternalDString(
}
flags = TCL_ENCODING_START | TCL_ENCODING_END;
while (1) {
- result = (*encodingPtr->fromUtfProc)(encodingPtr->clientData, src,
+ result = encodingPtr->fromUtfProc(encodingPtr->clientData, src,
srcLen, flags, &state, dst, dstLen, &srcRead, &dstWrote,
&dstChars);
soFar = dst + dstWrote - Tcl_DStringValue(dstPtr);
@@ -1292,7 +1345,7 @@ Tcl_UtfToExternal(
Tcl_Interp *interp, /* Interp for error return, if not NULL. */
Tcl_Encoding encoding, /* The encoding for the converted string, or
* NULL for the default system encoding. */
- CONST char *src, /* Source string in UTF-8. */
+ const char *src, /* Source string in UTF-8. */
int srcLen, /* Source string length in bytes, or < 0 for
* strlen(). */
int flags, /* Conversion control flags. */
@@ -1317,7 +1370,7 @@ Tcl_UtfToExternal(
* correspond to the bytes stored in the
* output buffer. */
{
- Encoding *encodingPtr;
+ const Encoding *encodingPtr;
int result, srcRead, dstWrote, dstChars;
Tcl_EncodingState state;
@@ -1346,7 +1399,7 @@ Tcl_UtfToExternal(
}
dstLen -= encodingPtr->nullSize;
- result = (*encodingPtr->fromUtfProc)(encodingPtr->clientData, src, srcLen,
+ result = encodingPtr->fromUtfProc(encodingPtr->clientData, src, srcLen,
flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr,
dstCharsPtr);
if (encodingPtr->nullSize == 2) {
@@ -1374,10 +1427,10 @@ Tcl_UtfToExternal(
*
*---------------------------------------------------------------------------
*/
-
+#undef Tcl_FindExecutable
void
Tcl_FindExecutable(
- CONST char *argv0) /* The value of the application's argv[0]
+ const char *argv0) /* The value of the application's argv[0]
* (native). */
{
TclInitSubsystems();
@@ -1393,9 +1446,9 @@ Tcl_FindExecutable(
* Open the file believed to hold data for the encoding, "name".
*
* Results:
- * Returns the readable Tcl_Channel from opening the file, or NULL if the
- * file could not be successfully opened. If NULL was returned, an error
- * message is left in interp's result object, unless interp was NULL.
+ * Returns the readable Tcl_Channel from opening the file, or NULL if the
+ * file could not be successfully opened. If NULL was returned, an error
+ * message is left in interp's result object, unless interp was NULL.
*
* Side effects:
* Channel may be opened. Information about the filesystem may be cached
@@ -1407,12 +1460,12 @@ Tcl_FindExecutable(
static Tcl_Channel
OpenEncodingFileChannel(
Tcl_Interp *interp, /* Interp for error reporting, if not NULL. */
- CONST char *name) /* The name of the encoding file on disk and
+ const char *name) /* The name of the encoding file on disk and
* also the name for new encoding. */
{
Tcl_Obj *nameObj = Tcl_NewStringObj(name, -1);
Tcl_Obj *fileNameObj = Tcl_DuplicateObj(nameObj);
- Tcl_Obj *searchPath = Tcl_DuplicateObj(TclGetEncodingSearchPath());
+ Tcl_Obj *searchPath = Tcl_DuplicateObj(Tcl_GetEncodingSearchPath());
Tcl_Obj *map = TclGetProcessGlobalValue(&encodingFileMap);
Tcl_Obj **dir, *path, *directory = NULL;
Tcl_Channel chan = NULL;
@@ -1437,7 +1490,8 @@ OpenEncodingFileChannel(
}
}
if (!verified) {
- CONST char *dirString = Tcl_GetString(directory);
+ const char *dirString = Tcl_GetString(directory);
+
for (i=0; i<numDirs && !verified; i++) {
if (strcmp(dirString, Tcl_GetString(dir[i])) == 0) {
verified = 1;
@@ -1490,7 +1544,9 @@ OpenEncodingFileChannel(
}
if ((NULL == chan) && (interp != NULL)) {
- Tcl_AppendResult(interp, "unknown encoding \"", name, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "unknown encoding \"%s\"", name));
+ Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ENCODING", name, NULL);
}
Tcl_DecrRefCount(fileNameObj);
Tcl_DecrRefCount(nameObj);
@@ -1522,7 +1578,7 @@ OpenEncodingFileChannel(
static Tcl_Encoding
LoadEncodingFile(
Tcl_Interp *interp, /* Interp for error reporting, if not NULL. */
- CONST char *name) /* The name of the encoding file on disk and
+ const char *name) /* The name of the encoding file on disk and
* also the name for new encoding. */
{
Tcl_Channel chan = NULL;
@@ -1563,7 +1619,9 @@ LoadEncodingFile(
break;
}
if ((encoding == NULL) && (interp != NULL)) {
- Tcl_AppendResult(interp, "invalid encoding file \"", name, "\"", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "invalid encoding file \"%s\"", name));
+ Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ENCODING", name, NULL);
}
Tcl_Close(NULL, chan);
@@ -1595,18 +1653,18 @@ LoadEncodingFile(
static Tcl_Encoding
LoadTableEncoding(
- CONST char *name, /* Name for new encoding. */
+ const char *name, /* Name for new encoding. */
int type, /* Type of encoding (ENCODING_?????). */
Tcl_Channel chan) /* File containing new encoding. */
{
Tcl_DString lineString;
Tcl_Obj *objPtr;
char *line;
- int i, hi, lo, numPages, symbol, fallback;
+ int i, hi, lo, numPages, symbol, fallback, len;
unsigned char used[256];
- unsigned int size;
+ unsigned size;
TableEncodingData *dataPtr;
- unsigned short *pageMemPtr;
+ unsigned short *pageMemPtr, *page;
Tcl_EncodingType encType;
/*
@@ -1614,7 +1672,7 @@ LoadTableEncoding(
* sequences in the encoding files.
*/
- static char staticHex[] = {
+ static const char staticHex[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 ... 15 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16 ... 31 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 32 ... 47 */
@@ -1653,7 +1711,7 @@ LoadTableEncoding(
#undef PAGESIZE
#define PAGESIZE (256 * sizeof(unsigned short))
- dataPtr = (TableEncodingData *) ckalloc(sizeof(TableEncodingData));
+ dataPtr = ckalloc(sizeof(TableEncodingData));
memset(dataPtr, 0, sizeof(TableEncodingData));
dataPtr->fallback = fallback;
@@ -1665,7 +1723,7 @@ LoadTableEncoding(
*/
size = 256 * sizeof(unsigned short *) + numPages * PAGESIZE;
- dataPtr->toUnicode = (unsigned short **) ckalloc(size);
+ dataPtr->toUnicode = ckalloc(size);
memset(dataPtr->toUnicode, 0, size);
pageMemPtr = (unsigned short *) (dataPtr->toUnicode + 256);
@@ -1673,7 +1731,7 @@ LoadTableEncoding(
Tcl_IncrRefCount(objPtr);
for (i = 0; i < numPages; i++) {
int ch;
- char *p;
+ const char *p;
Tcl_ReadChars(chan, objPtr, 3 + 16 * (16 * 4 + 1), 0);
p = Tcl_GetString(objPtr);
@@ -1723,29 +1781,26 @@ LoadTableEncoding(
}
}
size = 256 * sizeof(unsigned short *) + numPages * PAGESIZE;
- dataPtr->fromUnicode = (unsigned short **) ckalloc(size);
+ dataPtr->fromUnicode = ckalloc(size);
memset(dataPtr->fromUnicode, 0, size);
pageMemPtr = (unsigned short *) (dataPtr->fromUnicode + 256);
for (hi = 0; hi < 256; hi++) {
if (dataPtr->toUnicode[hi] == NULL) {
dataPtr->toUnicode[hi] = emptyPage;
- } else {
- for (lo = 0; lo < 256; lo++) {
- int ch;
-
- ch = dataPtr->toUnicode[hi][lo];
- if (ch != 0) {
- unsigned short *page;
-
- page = dataPtr->fromUnicode[ch >> 8];
- if (page == NULL) {
- page = pageMemPtr;
- pageMemPtr += 256;
- dataPtr->fromUnicode[ch >> 8] = page;
- }
- page[ch & 0xff] = (unsigned short) ((hi << 8) + lo);
+ continue;
+ }
+ for (lo = 0; lo < 256; lo++) {
+ int ch = dataPtr->toUnicode[hi][lo];
+
+ if (ch != 0) {
+ page = dataPtr->fromUnicode[ch >> 8];
+ if (page == NULL) {
+ page = pageMemPtr;
+ pageMemPtr += 256;
+ dataPtr->fromUnicode[ch >> 8] = page;
}
+ page[ch & 0xff] = (unsigned short) ((hi << 8) + lo);
}
}
}
@@ -1764,8 +1819,6 @@ LoadTableEncoding(
}
}
if (symbol) {
- unsigned short *page;
-
/*
* Make a special symbol encoding that not only maps the symbol
* characters from their Unicode code points down into page 0, but
@@ -1773,7 +1826,7 @@ LoadTableEncoding(
* is so that a symbol font can be used to display a simple string
* like "abcd" and have alpha, beta, chi, delta show up, rather than
* have "unknown" chars show up because strictly speaking the symbol
- * font doesn't have glyphs for those low ascii chars.
+ * font doesn't have glyphs for those low ASCII chars.
*/
page = dataPtr->fromUnicode[0];
@@ -1798,56 +1851,77 @@ LoadTableEncoding(
*/
Tcl_DStringInit(&lineString);
- do {
- int len;
+
+ /*
+ * Skip leading empty lines.
+ */
+
+ while ((len = Tcl_Gets(chan, &lineString)) == 0) {
+ /* empty body */
+ }
+ if (len < 0) {
+ goto doneParse;
+ }
+
+ /*
+ * Require that it starts with an 'R'.
+ */
+
+ line = Tcl_DStringValue(&lineString);
+ if (line[0] != 'R') {
+ goto doneParse;
+ }
+
+ /*
+ * Read lines from the encoding until EOF.
+ */
+
+ for (TclDStringClear(&lineString);
+ (len = Tcl_Gets(chan, &lineString)) >= 0;
+ TclDStringClear(&lineString)) {
+ const unsigned char *p;
+ int to, from;
/*
- * Skip leading empty lines.
+ * Skip short lines.
*/
- while ((len = Tcl_Gets(chan, &lineString)) == 0)
- ;
-
- if (len < 0) {
- break;
- }
- line = Tcl_DStringValue(&lineString);
- if (line[0] != 'R') {
- break;
+ if (len < 5) {
+ continue;
}
- for (Tcl_DStringSetLength(&lineString, 0);
- (len = Tcl_Gets(chan, &lineString)) >= 0;
- Tcl_DStringSetLength(&lineString, 0)) {
- unsigned char* p;
- int to, from;
- if (len < 5) {
- continue;
- }
- p = (unsigned char*) Tcl_DStringValue(&lineString);
- to = (staticHex[p[0]] << 12) + (staticHex[p[1]] << 8)
+ /*
+ * Parse the line as a sequence of hex digits.
+ */
+
+ p = (const unsigned char *) Tcl_DStringValue(&lineString);
+ to = (staticHex[p[0]] << 12) + (staticHex[p[1]] << 8)
+ + (staticHex[p[2]] << 4) + staticHex[p[3]];
+ if (to == 0) {
+ continue;
+ }
+ for (p += 5, len -= 5; len >= 0 && *p; p += 5, len -= 5) {
+ from = (staticHex[p[0]] << 12) + (staticHex[p[1]] << 8)
+ (staticHex[p[2]] << 4) + staticHex[p[3]];
- if (to == 0) {
- continue;
- }
- for (p += 5, len -= 5; len >= 0 && *p; p += 5, len -= 5) {
- from = (staticHex[p[0]] << 12) + (staticHex[p[1]] << 8)
- + (staticHex[p[2]] << 4) + staticHex[p[3]];
- if (from == 0) {
- continue;
- }
- dataPtr->fromUnicode[from >> 8][from & 0xff] = to;
+ if (from == 0) {
+ continue;
}
+ dataPtr->fromUnicode[from >> 8][from & 0xff] = to;
}
- } while (0);
+ }
+ doneParse:
Tcl_DStringFree(&lineString);
+ /*
+ * Package everything into an encoding structure.
+ */
+
encType.encodingName = name;
encType.toUtfProc = TableToUtfProc;
encType.fromUtfProc = TableFromUtfProc;
encType.freeProc = TableFreeProc;
encType.nullSize = (type == ENCODING_DOUBLEBYTE) ? 2 : 1;
- encType.clientData = (ClientData) dataPtr;
+ encType.clientData = dataPtr;
return Tcl_CreateEncoding(&encType);
}
@@ -1876,11 +1950,11 @@ LoadTableEncoding(
static Tcl_Encoding
LoadEscapeEncoding(
- CONST char *name, /* Name for new encoding. */
+ const char *name, /* Name for new encoding. */
Tcl_Channel chan) /* File containing new encoding. */
{
int i;
- unsigned int size;
+ unsigned size;
Tcl_DString escapeData;
char init[16], final[16];
EscapeEncodingData *dataPtr;
@@ -1892,7 +1966,7 @@ LoadEscapeEncoding(
while (1) {
int argc;
- CONST char **argv;
+ const char **argv;
char *line;
Tcl_DString lineString;
@@ -1902,11 +1976,12 @@ LoadEscapeEncoding(
}
line = Tcl_DStringValue(&lineString);
if (Tcl_SplitList(NULL, line, &argc, &argv) != TCL_OK) {
+ Tcl_DStringFree(&lineString);
continue;
}
if (argc >= 2) {
if (strcmp(argv[0], "name") == 0) {
- ;
+ /* do nothing */
} else if (strcmp(argv[0], "init") == 0) {
strncpy(init, argv[1], sizeof(init));
init[sizeof(init) - 1] = '\0';
@@ -1915,6 +1990,7 @@ LoadEscapeEncoding(
final[sizeof(final) - 1] = '\0';
} else {
EscapeSubTable est;
+ Encoding *e;
strncpy(est.sequence, argv[1], sizeof(est.sequence));
est.sequence[sizeof(est.sequence) - 1] = '\0';
@@ -1927,26 +2003,30 @@ LoadEscapeEncoding(
* To avoid infinite recursion in [encoding system iso2022-*]
*/
- Tcl_GetEncoding(NULL, est.name);
-
- est.encodingPtr = NULL;
+ e = (Encoding *) Tcl_GetEncoding(NULL, est.name);
+ if ((e != NULL) && (e->toUtfProc != TableToUtfProc)
+ && (e->toUtfProc != Iso88591ToUtfProc)) {
+ Tcl_FreeEncoding((Tcl_Encoding) e);
+ e = NULL;
+ }
+ est.encodingPtr = e;
Tcl_DStringAppend(&escapeData, (char *) &est, sizeof(est));
}
}
- ckfree((char *) argv);
+ ckfree(argv);
Tcl_DStringFree(&lineString);
}
size = sizeof(EscapeEncodingData) - sizeof(EscapeSubTable)
+ Tcl_DStringLength(&escapeData);
- dataPtr = (EscapeEncodingData *) ckalloc(size);
+ dataPtr = ckalloc(size);
dataPtr->initLen = strlen(init);
- strcpy(dataPtr->init, init);
+ memcpy(dataPtr->init, init, (unsigned) dataPtr->initLen + 1);
dataPtr->finalLen = strlen(final);
- strcpy(dataPtr->final, final);
+ memcpy(dataPtr->final, final, (unsigned) dataPtr->finalLen + 1);
dataPtr->numSubTables =
Tcl_DStringLength(&escapeData) / sizeof(EscapeSubTable);
- memcpy((VOID *) dataPtr->subTables, (VOID *) Tcl_DStringValue(&escapeData),
+ memcpy(dataPtr->subTables, Tcl_DStringValue(&escapeData),
(size_t) Tcl_DStringLength(&escapeData));
Tcl_DStringFree(&escapeData);
@@ -1961,12 +2041,16 @@ LoadEscapeEncoding(
dataPtr->prefixBytes[UCHAR(dataPtr->final[0])] = 1;
}
+ /*
+ * Package everything into an encoding structure.
+ */
+
type.encodingName = name;
type.toUtfProc = EscapeToUtfProc;
type.fromUtfProc = EscapeFromUtfProc;
type.freeProc = EscapeFreeProc;
type.nullSize = 1;
- type.clientData = (ClientData) dataPtr;
+ type.clientData = dataPtr;
return Tcl_CreateEncoding(&type);
}
@@ -1992,7 +2076,7 @@ LoadEscapeEncoding(
static int
BinaryProc(
ClientData clientData, /* Not used. */
- CONST char *src, /* Source string (unknown encoding). */
+ const char *src, /* Source string (unknown encoding). */
int srcLen, /* Source string length in bytes. */
int flags, /* Conversion control flags. */
Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
@@ -2028,9 +2112,7 @@ BinaryProc(
*srcReadPtr = srcLen;
*dstWrotePtr = srcLen;
*dstCharsPtr = srcLen;
- for ( ; --srcLen >= 0; ) {
- *dst++ = *src++;
- }
+ memcpy(dst, src, (size_t) srcLen);
return result;
}
@@ -2055,7 +2137,7 @@ BinaryProc(
static int
UtfIntToUtfExtProc(
ClientData clientData, /* Not used. */
- CONST char *src, /* Source string in UTF-8. */
+ const char *src, /* Source string in UTF-8. */
int srcLen, /* Source string length in bytes. */
int flags, /* Conversion control flags. */
Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
@@ -2088,9 +2170,9 @@ UtfIntToUtfExtProc(
*
* UtfExtToUtfIntProc --
*
- * Convert from UTF-8 to UTF-8 while converting null-bytes from
- * the official representation (0x00) to Tcl's internal
- * representation (0xc0, 0x80). See UtfToUtfProc for details.
+ * Convert from UTF-8 to UTF-8 while converting null-bytes from the
+ * official representation (0x00) to Tcl's internal representation (0xc0,
+ * 0x80). See UtfToUtfProc for details.
*
* Results:
* Returns TCL_OK if conversion was successful.
@@ -2100,10 +2182,11 @@ UtfIntToUtfExtProc(
*
*-------------------------------------------------------------------------
*/
+
static int
UtfExtToUtfIntProc(
ClientData clientData, /* Not used. */
- CONST char *src, /* Source string in UTF-8. */
+ const char *src, /* Source string in UTF-8. */
int srcLen, /* Source string length in bytes. */
int flags, /* Conversion control flags. */
Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
@@ -2152,7 +2235,7 @@ UtfExtToUtfIntProc(
static int
UtfToUtfProc(
ClientData clientData, /* Not used. */
- CONST char *src, /* Source string in UTF-8. */
+ const char *src, /* Source string in UTF-8. */
int srcLen, /* Source string length in bytes. */
int flags, /* Conversion control flags. */
Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
@@ -2179,8 +2262,8 @@ UtfToUtfProc(
* representation to real null-bytes or vice
* versa. */
{
- CONST char *srcStart, *srcEnd, *srcClose;
- char *dstStart, *dstEnd;
+ const char *srcStart, *srcEnd, *srcClose;
+ const char *dstStart, *dstEnd;
int result, numChars;
Tcl_UniChar ch;
@@ -2225,6 +2308,16 @@ UtfToUtfProc(
*dst++ = 0;
src += 2;
+ } else if (!Tcl_UtfCharComplete(src, srcEnd - src)) {
+ /*
+ * Always check before using Tcl_UtfToUniChar. Not doing can so
+ * cause it run beyond the endof the buffer! If we happen such an
+ * incomplete char its byts are made to represent themselves.
+ */
+
+ ch = (unsigned char) *src;
+ src += 1;
+ dst += Tcl_UniCharToUtf(ch, dst);
} else {
src += Tcl_UtfToUniChar(src, &ch);
dst += Tcl_UniCharToUtf(ch, dst);
@@ -2256,7 +2349,7 @@ UtfToUtfProc(
static int
UnicodeToUtfProc(
ClientData clientData, /* Not used. */
- CONST char *src, /* Source string in Unicode. */
+ const char *src, /* Source string in Unicode. */
int srcLen, /* Source string length in bytes. */
int flags, /* Conversion control flags. */
Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
@@ -2280,9 +2373,10 @@ UnicodeToUtfProc(
* correspond to the bytes stored in the
* output buffer. */
{
- CONST Tcl_UniChar *wSrc, *wSrcStart, *wSrcEnd;
- char *dstEnd, *dstStart;
+ const char *srcStart, *srcEnd;
+ const char *dstEnd, *dstStart;
int result, numChars;
+ Tcl_UniChar ch;
result = TCL_OK;
if ((srcLen % sizeof(Tcl_UniChar)) != 0) {
@@ -2291,33 +2385,33 @@ UnicodeToUtfProc(
srcLen *= sizeof(Tcl_UniChar);
}
- wSrc = (Tcl_UniChar *) src;
-
- wSrcStart = (Tcl_UniChar *) src;
- wSrcEnd = (Tcl_UniChar *) (src + srcLen);
+ srcStart = src;
+ srcEnd = src + srcLen;
dstStart = dst;
dstEnd = dst + dstLen - TCL_UTF_MAX;
- for (numChars = 0; wSrc < wSrcEnd; numChars++) {
+ for (numChars = 0; src < srcEnd; numChars++) {
if (dst > dstEnd) {
result = TCL_CONVERT_NOSPACE;
break;
}
/*
- * Special case for 1-byte utf chars for speed.
+ * Special case for 1-byte utf chars for speed. Make sure we work with
+ * Tcl_UniChar-size data.
*/
- if (*wSrc && *wSrc < 0x80) {
- *dst++ = (char) *wSrc;
+ ch = *(Tcl_UniChar *)src;
+ if (ch && ch < 0x80) {
+ *dst++ = (ch & 0xFF);
} else {
- dst += Tcl_UniCharToUtf(*wSrc, dst);
+ dst += Tcl_UniCharToUtf(ch, dst);
}
- wSrc++;
+ src += sizeof(Tcl_UniChar);
}
- *srcReadPtr = (char *) wSrc - (char *) wSrcStart;
+ *srcReadPtr = src - srcStart;
*dstWrotePtr = dst - dstStart;
*dstCharsPtr = numChars;
return result;
@@ -2343,7 +2437,7 @@ static int
UtfToUnicodeProc(
ClientData clientData, /* TableEncodingData that specifies
* encoding. */
- CONST char *src, /* Source string in UTF-8. */
+ const char *src, /* Source string in UTF-8. */
int srcLen, /* Source string length in bytes. */
int flags, /* Conversion control flags. */
Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
@@ -2367,9 +2461,9 @@ UtfToUnicodeProc(
* correspond to the bytes stored in the
* output buffer. */
{
- CONST char *srcStart, *srcEnd, *srcClose;
- Tcl_UniChar *wDst, *wDstStart, *wDstEnd;
+ const char *srcStart, *srcEnd, *srcClose, *dstStart, *dstEnd;
int result, numChars;
+ Tcl_UniChar ch;
srcStart = src;
srcEnd = src + srcLen;
@@ -2378,9 +2472,8 @@ UtfToUnicodeProc(
srcClose -= TCL_UTF_MAX;
}
- wDst = (Tcl_UniChar *) dst;
- wDstStart = (Tcl_UniChar *) dst;
- wDstEnd = (Tcl_UniChar *) (dst + dstLen - sizeof(Tcl_UniChar));
+ dstStart = dst;
+ dstEnd = dst + dstLen - sizeof(Tcl_UniChar);
result = TCL_OK;
for (numChars = 0; src < srcEnd; numChars++) {
@@ -2393,16 +2486,28 @@ UtfToUnicodeProc(
result = TCL_CONVERT_MULTIBYTE;
break;
}
- if (wDst > wDstEnd) {
+ if (dst > dstEnd) {
result = TCL_CONVERT_NOSPACE;
break;
- }
- src += TclUtfToUniChar(src, wDst);
- wDst++;
- }
+ }
+ src += TclUtfToUniChar(src, &ch);
+
+ /*
+ * Need to handle this in a way that won't cause misalignment by
+ * casting dst to a Tcl_UniChar. [Bug 1122671]
+ * XXX: This hard-codes the assumed size of Tcl_UniChar as 2.
+ */
+#ifdef WORDS_BIGENDIAN
+ *dst++ = (ch >> 8);
+ *dst++ = (ch & 0xFF);
+#else
+ *dst++ = (ch & 0xFF);
+ *dst++ = (ch >> 8);
+#endif
+ }
*srcReadPtr = src - srcStart;
- *dstWrotePtr = (char *) wDst - (char *) wDstStart;
+ *dstWrotePtr = dst - dstStart;
*dstCharsPtr = numChars;
return result;
}
@@ -2428,7 +2533,7 @@ static int
TableToUtfProc(
ClientData clientData, /* TableEncodingData that specifies
* encoding. */
- CONST char *src, /* Source string in specified encoding. */
+ const char *src, /* Source string in specified encoding. */
int srcLen, /* Source string length in bytes. */
int flags, /* Conversion control flags. */
Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
@@ -2452,13 +2557,13 @@ TableToUtfProc(
* correspond to the bytes stored in the
* output buffer. */
{
- CONST char *srcStart, *srcEnd;
- char *dstEnd, *dstStart, *prefixBytes;
+ const char *srcStart, *srcEnd;
+ const char *dstEnd, *dstStart, *prefixBytes;
int result, byte, numChars;
Tcl_UniChar ch;
- unsigned short **toUnicode;
- unsigned short *pageZero;
- TableEncodingData *dataPtr;
+ const unsigned short *const *toUnicode;
+ const unsigned short *pageZero;
+ TableEncodingData *dataPtr = clientData;
srcStart = src;
srcEnd = src + srcLen;
@@ -2466,8 +2571,7 @@ TableToUtfProc(
dstStart = dst;
dstEnd = dst + dstLen - TCL_UTF_MAX;
- dataPtr = (TableEncodingData *) clientData;
- toUnicode = dataPtr->toUnicode;
+ toUnicode = (const unsigned short *const *) dataPtr->toUnicode;
prefixBytes = dataPtr->prefixBytes;
pageZero = toUnicode[0];
@@ -2499,9 +2603,11 @@ TableToUtfProc(
}
ch = (Tcl_UniChar) byte;
}
+
/*
* Special case for 1-byte utf chars for speed.
*/
+
if (ch && ch < 0x80) {
*dst++ = (char) ch;
} else {
@@ -2537,7 +2643,7 @@ static int
TableFromUtfProc(
ClientData clientData, /* TableEncodingData that specifies
* encoding. */
- CONST char *src, /* Source string in UTF-8. */
+ const char *src, /* Source string in UTF-8. */
int srcLen, /* Source string length in bytes. */
int flags, /* Conversion control flags. */
Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
@@ -2561,18 +2667,17 @@ TableFromUtfProc(
* correspond to the bytes stored in the
* output buffer. */
{
- CONST char *srcStart, *srcEnd, *srcClose;
- char *dstStart, *dstEnd, *prefixBytes;
+ const char *srcStart, *srcEnd, *srcClose;
+ const char *dstStart, *dstEnd, *prefixBytes;
Tcl_UniChar ch;
int result, len, word, numChars;
- TableEncodingData *dataPtr;
- unsigned short **fromUnicode;
+ TableEncodingData *dataPtr = clientData;
+ const unsigned short *const *fromUnicode;
result = TCL_OK;
- dataPtr = (TableEncodingData *) clientData;
prefixBytes = dataPtr->prefixBytes;
- fromUnicode = dataPtr->fromUnicode;
+ fromUnicode = (const unsigned short *const *) dataPtr->fromUnicode;
srcStart = src;
srcEnd = src + srcLen;
@@ -2641,6 +2746,192 @@ TableFromUtfProc(
}
/*
+ *-------------------------------------------------------------------------
+ *
+ * Iso88591ToUtfProc --
+ *
+ * Convert from the "iso8859-1" encoding into UTF-8.
+ *
+ * Results:
+ * Returns TCL_OK if conversion was successful.
+ *
+ * Side effects:
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int
+Iso88591ToUtfProc(
+ ClientData clientData, /* Ignored. */
+ const char *src, /* Source string in specified encoding. */
+ int srcLen, /* Source string length in bytes. */
+ int flags, /* Conversion control flags. */
+ Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
+ * information used during a piecewise
+ * conversion. Contents of statePtr are
+ * initialized and/or reset by conversion
+ * routine under control of flags argument. */
+ char *dst, /* Output buffer in which converted string is
+ * stored. */
+ int dstLen, /* The maximum length of output buffer in
+ * bytes. */
+ int *srcReadPtr, /* Filled with the number of bytes from the
+ * source string that were converted. This may
+ * be less than the original source length if
+ * there was a problem converting some source
+ * characters. */
+ int *dstWrotePtr, /* Filled with the number of bytes that were
+ * stored in the output buffer as a result of
+ * the conversion. */
+ int *dstCharsPtr) /* Filled with the number of characters that
+ * correspond to the bytes stored in the
+ * output buffer. */
+{
+ const char *srcStart, *srcEnd;
+ const char *dstEnd, *dstStart;
+ int result, numChars;
+
+ srcStart = src;
+ srcEnd = src + srcLen;
+
+ dstStart = dst;
+ dstEnd = dst + dstLen - TCL_UTF_MAX;
+
+ result = TCL_OK;
+ for (numChars = 0; src < srcEnd; numChars++) {
+ Tcl_UniChar ch;
+
+ if (dst > dstEnd) {
+ result = TCL_CONVERT_NOSPACE;
+ break;
+ }
+ ch = (Tcl_UniChar) *((unsigned char *) src);
+
+ /*
+ * Special case for 1-byte utf chars for speed.
+ */
+
+ if (ch && ch < 0x80) {
+ *dst++ = (char) ch;
+ } else {
+ dst += Tcl_UniCharToUtf(ch, dst);
+ }
+ src++;
+ }
+
+ *srcReadPtr = src - srcStart;
+ *dstWrotePtr = dst - dstStart;
+ *dstCharsPtr = numChars;
+ return result;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * Iso88591FromUtfProc --
+ *
+ * Convert from UTF-8 into the encoding "iso8859-1".
+ *
+ * Results:
+ * Returns TCL_OK if conversion was successful.
+ *
+ * Side effects:
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int
+Iso88591FromUtfProc(
+ ClientData clientData, /* Ignored. */
+ const char *src, /* Source string in UTF-8. */
+ int srcLen, /* Source string length in bytes. */
+ int flags, /* Conversion control flags. */
+ Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
+ * information used during a piecewise
+ * conversion. Contents of statePtr are
+ * initialized and/or reset by conversion
+ * routine under control of flags argument. */
+ char *dst, /* Output buffer in which converted string is
+ * stored. */
+ int dstLen, /* The maximum length of output buffer in
+ * bytes. */
+ int *srcReadPtr, /* Filled with the number of bytes from the
+ * source string that were converted. This may
+ * be less than the original source length if
+ * there was a problem converting some source
+ * characters. */
+ int *dstWrotePtr, /* Filled with the number of bytes that were
+ * stored in the output buffer as a result of
+ * the conversion. */
+ int *dstCharsPtr) /* Filled with the number of characters that
+ * correspond to the bytes stored in the
+ * output buffer. */
+{
+ const char *srcStart, *srcEnd, *srcClose;
+ const char *dstStart, *dstEnd;
+ int result, numChars;
+
+ result = TCL_OK;
+
+ srcStart = src;
+ srcEnd = src + srcLen;
+ srcClose = srcEnd;
+ if ((flags & TCL_ENCODING_END) == 0) {
+ srcClose -= TCL_UTF_MAX;
+ }
+
+ dstStart = dst;
+ dstEnd = dst + dstLen - 1;
+
+ for (numChars = 0; src < srcEnd; numChars++) {
+ Tcl_UniChar ch;
+ int len;
+
+ if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
+ /*
+ * If there is more string to follow, this will ensure that the
+ * last UTF-8 character in the source buffer hasn't been cut off.
+ */
+
+ result = TCL_CONVERT_MULTIBYTE;
+ break;
+ }
+ len = TclUtfToUniChar(src, &ch);
+
+ /*
+ * Check for illegal characters.
+ */
+
+ if (ch > 0xff) {
+ if (flags & TCL_ENCODING_STOPONERROR) {
+ result = TCL_CONVERT_UNKNOWN;
+ break;
+ }
+
+ /*
+ * Plunge on, using '?' as a fallback character.
+ */
+
+ ch = (Tcl_UniChar) '?';
+ }
+
+ if (dst > dstEnd) {
+ result = TCL_CONVERT_NOSPACE;
+ break;
+ }
+ *(dst++) = (char) ch;
+ src += len;
+ }
+
+ *srcReadPtr = src - srcStart;
+ *dstWrotePtr = dst - dstStart;
+ *dstCharsPtr = numChars;
+ return result;
+}
+
+/*
*---------------------------------------------------------------------------
*
* TableFreeProc --
@@ -2662,16 +2953,15 @@ TableFreeProc(
ClientData clientData) /* TableEncodingData that specifies
* encoding. */
{
- TableEncodingData *dataPtr;
+ TableEncodingData *dataPtr = clientData;
/*
* Make sure we aren't freeing twice on shutdown. [Bug 219314]
*/
- dataPtr = (TableEncodingData *) clientData;
- ckfree((char *) dataPtr->toUnicode);
- ckfree((char *) dataPtr->fromUnicode);
- ckfree((char *) dataPtr);
+ ckfree(dataPtr->toUnicode);
+ ckfree(dataPtr->fromUnicode);
+ ckfree(dataPtr);
}
/*
@@ -2695,7 +2985,7 @@ static int
EscapeToUtfProc(
ClientData clientData, /* EscapeEncodingData that specifies
* encoding. */
- CONST char *src, /* Source string in specified encoding. */
+ const char *src, /* Source string in specified encoding. */
int srcLen, /* Source string length in bytes. */
int flags, /* Conversion control flags. */
Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
@@ -2719,20 +3009,16 @@ EscapeToUtfProc(
* correspond to the bytes stored in the
* output buffer. */
{
- EscapeEncodingData *dataPtr;
- char *prefixBytes, *tablePrefixBytes;
- unsigned short **tableToUnicode;
- Encoding *encodingPtr;
+ EscapeEncodingData *dataPtr = clientData;
+ const char *prefixBytes, *tablePrefixBytes, *srcStart, *srcEnd;
+ const unsigned short *const *tableToUnicode;
+ const Encoding *encodingPtr;
int state, result, numChars;
- CONST char *srcStart, *srcEnd;
- char *dstStart, *dstEnd;
+ const char *dstStart, *dstEnd;
result = TCL_OK;
-
tablePrefixBytes = NULL; /* lint. */
tableToUnicode = NULL; /* lint. */
-
- dataPtr = (EscapeEncodingData *) clientData;
prefixBytes = dataPtr->prefixBytes;
encodingPtr = NULL;
@@ -2742,7 +3028,7 @@ EscapeToUtfProc(
dstStart = dst;
dstEnd = dst + dstLen - TCL_UTF_MAX;
- state = (int) *statePtr;
+ state = PTR2INT(*statePtr);
if (flags & TCL_ENCODING_START) {
state = 0;
}
@@ -2756,9 +3042,9 @@ EscapeToUtfProc(
}
byte = *((unsigned char *) src);
if (prefixBytes[byte]) {
- unsigned int left, len, longest;
+ unsigned left, len, longest;
int checked, i;
- EscapeSubTable *subTablePtr;
+ const EscapeSubTable *subTablePtr;
/*
* Saw the beginning of an escape sequence.
@@ -2856,9 +3142,10 @@ EscapeToUtfProc(
TableEncodingData *tableDataPtr;
encodingPtr = GetTableEncoding(dataPtr, state);
- tableDataPtr = (TableEncodingData *) encodingPtr->clientData;
+ tableDataPtr = encodingPtr->clientData;
tablePrefixBytes = tableDataPtr->prefixBytes;
- tableToUnicode = tableDataPtr->toUnicode;
+ tableToUnicode = (const unsigned short *const*)
+ tableDataPtr->toUnicode;
}
if (tablePrefixBytes[byte]) {
@@ -2881,7 +3168,7 @@ EscapeToUtfProc(
numChars++;
}
- *statePtr = (Tcl_EncodingState) state;
+ *statePtr = (Tcl_EncodingState) INT2PTR(state);
*srcReadPtr = src - srcStart;
*dstWrotePtr = dst - dstStart;
*dstCharsPtr = numChars;
@@ -2909,7 +3196,7 @@ static int
EscapeFromUtfProc(
ClientData clientData, /* EscapeEncodingData that specifies
* encoding. */
- CONST char *src, /* Source string in UTF-8. */
+ const char *src, /* Source string in UTF-8. */
int srcLen, /* Source string length in bytes. */
int flags, /* Conversion control flags. */
Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
@@ -2933,19 +3220,17 @@ EscapeFromUtfProc(
* correspond to the bytes stored in the
* output buffer. */
{
- EscapeEncodingData *dataPtr;
- Encoding *encodingPtr;
- CONST char *srcStart, *srcEnd, *srcClose;
- char *dstStart, *dstEnd;
+ EscapeEncodingData *dataPtr = clientData;
+ const Encoding *encodingPtr;
+ const char *srcStart, *srcEnd, *srcClose;
+ const char *dstStart, *dstEnd;
int state, result, numChars;
- TableEncodingData *tableDataPtr;
- char *tablePrefixBytes;
- unsigned short **tableFromUnicode;
+ const TableEncodingData *tableDataPtr;
+ const char *tablePrefixBytes;
+ const unsigned short *const *tableFromUnicode;
result = TCL_OK;
- dataPtr = (EscapeEncodingData *) clientData;
-
srcStart = src;
srcEnd = src + srcLen;
srcClose = srcEnd;
@@ -2957,30 +3242,31 @@ EscapeFromUtfProc(
dstEnd = dst + dstLen - 1;
/*
- * RFC1468 states that the text starts in ASCII, and switches to Japanese
+ * RFC 1468 states that the text starts in ASCII, and switches to Japanese
* characters, and that the text must end in ASCII. [Patch 474358]
*/
if (flags & TCL_ENCODING_START) {
state = 0;
- if (dst + dataPtr->initLen > dstEnd) {
+ if ((dst + dataPtr->initLen) > dstEnd) {
*srcReadPtr = 0;
*dstWrotePtr = 0;
return TCL_CONVERT_NOSPACE;
}
- memcpy((VOID *)dst, (VOID *)dataPtr->init, (size_t)dataPtr->initLen);
+ memcpy(dst, dataPtr->init, (size_t)dataPtr->initLen);
dst += dataPtr->initLen;
} else {
- state = (int) *statePtr;
+ state = PTR2INT(*statePtr);
}
encodingPtr = GetTableEncoding(dataPtr, state);
- tableDataPtr = (TableEncodingData *) encodingPtr->clientData;
+ tableDataPtr = encodingPtr->clientData;
tablePrefixBytes = tableDataPtr->prefixBytes;
- tableFromUnicode = tableDataPtr->fromUnicode;
+ tableFromUnicode = (const unsigned short *const *)
+ tableDataPtr->fromUnicode;
for (numChars = 0; src < srcEnd; numChars++) {
- unsigned int len;
+ unsigned len;
int word;
Tcl_UniChar ch;
@@ -2998,13 +3284,13 @@ EscapeFromUtfProc(
if ((word == 0) && (ch != 0)) {
int oldState;
- EscapeSubTable *subTablePtr;
+ const EscapeSubTable *subTablePtr;
oldState = state;
for (state = 0; state < dataPtr->numSubTables; state++) {
encodingPtr = GetTableEncoding(dataPtr, state);
- tableDataPtr = (TableEncodingData *) encodingPtr->clientData;
- word = tableDataPtr->fromUnicode[(ch >> 8)][ch & 0xff];
+ tableDataPtr = encodingPtr->clientData;
+ word = tableDataPtr->fromUnicode[(ch >> 8)][ch & 0xff];
if (word != 0) {
break;
}
@@ -3017,12 +3303,13 @@ EscapeFromUtfProc(
break;
}
encodingPtr = GetTableEncoding(dataPtr, state);
- tableDataPtr = (TableEncodingData *) encodingPtr->clientData;
+ tableDataPtr = encodingPtr->clientData;
word = tableDataPtr->fallback;
}
- tablePrefixBytes = tableDataPtr->prefixBytes;
- tableFromUnicode = tableDataPtr->fromUnicode;
+ tablePrefixBytes = (const char *) tableDataPtr->prefixBytes;
+ tableFromUnicode = (const unsigned short *const *)
+ tableDataPtr->fromUnicode;
/*
* The state variable has the value of oldState when word is 0.
@@ -3044,7 +3331,7 @@ EscapeFromUtfProc(
result = TCL_CONVERT_NOSPACE;
break;
}
- memcpy((VOID *) dst, (VOID *) subTablePtr->sequence,
+ memcpy(dst, subTablePtr->sequence,
(size_t) subTablePtr->sequenceLen);
dst += subTablePtr->sequenceLen;
}
@@ -3070,22 +3357,31 @@ EscapeFromUtfProc(
}
if ((result == TCL_OK) && (flags & TCL_ENCODING_END)) {
- unsigned int len = dataPtr->subTables[0].sequenceLen;
- if (dst + dataPtr->finalLen + (state?len:0) > dstEnd) {
+ unsigned len = dataPtr->subTables[0].sequenceLen;
+
+ /*
+ * Certain encodings like iso2022-jp need to write an escape sequence
+ * after all characters have been converted. This logic checks that
+ * enough room is available in the buffer for the escape bytes. The
+ * TCL_ENCODING_END flag is cleared after a final escape sequence has
+ * been added to the buffer so that another call to this method does
+ * not attempt to append escape bytes a second time.
+ */
+
+ if ((dst + dataPtr->finalLen + (state?len:0)) > dstEnd) {
result = TCL_CONVERT_NOSPACE;
} else {
if (state) {
- memcpy((VOID *) dst, (VOID *) dataPtr->subTables[0].sequence,
- (size_t) len);
+ memcpy(dst, dataPtr->subTables[0].sequence, len);
dst += len;
}
- memcpy((VOID *) dst, (VOID *) dataPtr->final,
- (size_t) dataPtr->finalLen);
+ memcpy(dst, dataPtr->final, (size_t) dataPtr->finalLen);
dst += dataPtr->finalLen;
+ state &= ~TCL_ENCODING_END;
}
}
- *statePtr = (Tcl_EncodingState) state;
+ *statePtr = (Tcl_EncodingState) INT2PTR(state);
*srcReadPtr = src - srcStart;
*dstWrotePtr = dst - dstStart;
*dstCharsPtr = numChars;
@@ -3114,20 +3410,33 @@ EscapeFreeProc(
ClientData clientData) /* EscapeEncodingData that specifies
* encoding. */
{
- EscapeEncodingData *dataPtr;
+ EscapeEncodingData *dataPtr = clientData;
EscapeSubTable *subTablePtr;
int i;
- dataPtr = (EscapeEncodingData *) clientData;
if (dataPtr == NULL) {
return;
}
- subTablePtr = dataPtr->subTables;
- for (i = 0; i < dataPtr->numSubTables; i++) {
- FreeEncoding((Tcl_Encoding) subTablePtr->encodingPtr);
- subTablePtr++;
+
+ /*
+ * The subTables should be freed recursively in normal operation but not
+ * during TclFinalizeEncodingSubsystem because they are also present as a
+ * weak reference in the toplevel encodingTable (i.e., they don't have a
+ * +1 refcount for this), and unpredictable nuking order could remove them
+ * from under the following loop's feet. [Bug 2891556]
+ *
+ * The encodingsInitialized flag, being reset on entry to TFES, can serve
+ * as a "not in finalization" test.
+ */
+
+ if (encodingsInitialized) {
+ subTablePtr = dataPtr->subTables;
+ for (i = 0; i < dataPtr->numSubTables; i++) {
+ FreeEncoding((Tcl_Encoding) subTablePtr->encodingPtr);
+ subTablePtr++;
+ }
}
- ckfree((char *) dataPtr);
+ ckfree(dataPtr);
}
/*
@@ -3155,16 +3464,14 @@ GetTableEncoding(
EscapeEncodingData *dataPtr,/* Contains names of encodings. */
int state) /* Index in dataPtr of desired Encoding. */
{
- EscapeSubTable *subTablePtr;
- Encoding *encodingPtr;
-
- subTablePtr = &dataPtr->subTables[state];
- encodingPtr = subTablePtr->encodingPtr;
+ EscapeSubTable *subTablePtr = &dataPtr->subTables[state];
+ Encoding *encodingPtr = subTablePtr->encodingPtr;
if (encodingPtr == NULL) {
encodingPtr = (Encoding *) Tcl_GetEncoding(NULL, subTablePtr->name);
if ((encodingPtr == NULL)
- || (encodingPtr->toUtfProc != TableToUtfProc)) {
+ || (encodingPtr->toUtfProc != TableToUtfProc
+ && encodingPtr->toUtfProc != Iso88591ToUtfProc)) {
Tcl_Panic("EscapeToUtfProc: invalid sub table");
}
subTablePtr->encodingPtr = encodingPtr;
@@ -3193,7 +3500,7 @@ GetTableEncoding(
static size_t
unilen(
- CONST char *src)
+ const char *src)
{
unsigned short *p;
@@ -3211,7 +3518,7 @@ unilen(
*
* This is the fallback routine that sets the default value of the
* encoding search path if the application has not set one via a call to
- * TclSetEncodingSearchPath() by the first time the search path is needed
+ * Tcl_SetEncodingSearchPath() by the first time the search path is needed
* to load encoding data.
*
* The default encoding search path is produced by taking each directory
@@ -3233,42 +3540,43 @@ InitializeEncodingSearchPath(
int *lengthPtr,
Tcl_Encoding *encodingPtr)
{
- char *bytes;
+ const char *bytes;
int i, numDirs, numBytes;
- Tcl_Obj *libPath, *encodingObj = Tcl_NewStringObj("encoding", -1);
- Tcl_Obj *searchPath = Tcl_NewObj();
+ Tcl_Obj *libPathObj, *encodingObj, *searchPathObj;
+ TclNewLiteralStringObj(encodingObj, "encoding");
+ TclNewObj(searchPathObj);
Tcl_IncrRefCount(encodingObj);
- Tcl_IncrRefCount(searchPath);
- libPath = TclGetLibraryPath();
- Tcl_IncrRefCount(libPath);
- Tcl_ListObjLength(NULL, libPath, &numDirs);
+ Tcl_IncrRefCount(searchPathObj);
+ libPathObj = TclGetLibraryPath();
+ Tcl_IncrRefCount(libPathObj);
+ Tcl_ListObjLength(NULL, libPathObj, &numDirs);
for (i = 0; i < numDirs; i++) {
- Tcl_Obj *directory, *path;
+ Tcl_Obj *directoryObj, *pathObj;
Tcl_StatBuf stat;
- Tcl_ListObjIndex(NULL, libPath, i, &directory);
- path = Tcl_FSJoinToPath(directory, 1, &encodingObj);
- Tcl_IncrRefCount(path);
- if ((0 == Tcl_FSStat(path, &stat)) && S_ISDIR(stat.st_mode)) {
- Tcl_ListObjAppendElement(NULL, searchPath, path);
+ Tcl_ListObjIndex(NULL, libPathObj, i, &directoryObj);
+ pathObj = Tcl_FSJoinToPath(directoryObj, 1, &encodingObj);
+ Tcl_IncrRefCount(pathObj);
+ if ((0 == Tcl_FSStat(pathObj, &stat)) && S_ISDIR(stat.st_mode)) {
+ Tcl_ListObjAppendElement(NULL, searchPathObj, pathObj);
}
- Tcl_DecrRefCount(path);
+ Tcl_DecrRefCount(pathObj);
}
- Tcl_DecrRefCount(libPath);
+ Tcl_DecrRefCount(libPathObj);
Tcl_DecrRefCount(encodingObj);
*encodingPtr = libraryPath.encoding;
if (*encodingPtr) {
((Encoding *)(*encodingPtr))->refCount++;
}
- bytes = Tcl_GetStringFromObj(searchPath, &numBytes);
+ bytes = Tcl_GetStringFromObj(searchPathObj, &numBytes);
*lengthPtr = numBytes;
- *valuePtr = ckalloc((unsigned int) numBytes + 1);
- memcpy((VOID *) *valuePtr, (VOID *) bytes, (size_t) numBytes + 1);
- Tcl_DecrRefCount(searchPath);
+ *valuePtr = ckalloc(numBytes + 1);
+ memcpy(*valuePtr, bytes, (size_t) numBytes + 1);
+ Tcl_DecrRefCount(searchPathObj);
}
/*